From 1aad95d6a91ce7f05d58767a35d2b430fd309aa3 Mon Sep 17 00:00:00 2001 From: Joe Naegele Date: Fri, 13 Dec 2024 15:52:09 +0000 Subject: [PATCH] Remove more untested code and address PR feedback --- CMakeLists.txt | 13 +- cmake/CMakeLists.txt | 1 - cmake/FindPLplot.cmake | 50 - conda/meta.yaml | 2 - doc/source/conf.py | 4 +- doc/source/using.md | 13 - environment.yml | 2 - gadgets/CMakeLists.txt | 36 +- gadgets/T1/CMakeLists.txt | 28 - gadgets/T1/T1MocoGadget.cpp | 381 ------- gadgets/T1/config/MOLLI_T1_Moco.xml | 213 ---- gadgets/bart/BART_Recon.xml | 173 ---- gadgets/bart/BART_Recon_cloud.xml | 187 ---- gadgets/bart/BART_Recon_cloud_Standard.xml | 187 ---- gadgets/bart/CMakeLists.txt | 62 -- gadgets/bart/Sample_Grappa_Recon.sh | 49 - gadgets/bart/Sample_Grappa_Recon_Standard.sh | 49 - gadgets/bart/bart_helpers.cpp | 221 ---- gadgets/bart/bart_helpers.h | 45 - gadgets/bart/bart_logger.cpp | 37 - gadgets/bart/bartgadget.cpp | 598 ----------- gadgets/bart/bartgadget.h | 202 ---- gadgets/cartesian/CMakeLists.txt | 24 - .../cartesian/CartesianToGenericGadget.cpp | 94 -- gadgets/cartesian/CartesianToGenericGadget.h | 39 - gadgets/cmr/CMakeLists.txt | 4 +- .../CMR_2DT_RTCine_KspaceBinning_Cloud.xml | 279 ----- ...RTCine_KspaceBinning_MultiSeries_Cloud.xml | 257 ----- gadgets/dicom/CMakeLists.txt | 64 -- gadgets/dicom/DicomFinishGadget.cpp | 149 --- gadgets/dicom/DicomFinishGadget.h | 184 ---- gadgets/dicom/DicomImageWriter.cpp | 79 -- gadgets/dicom/DicomImageWriter.h | 23 - gadgets/dicom/dicom.xml | 74 -- gadgets/dicom/dicom_ismrmrd_utility.cpp | 972 ------------------ gadgets/dicom/dicom_ismrmrd_utility.h | 47 - gadgets/examples/CMakeLists.txt | 12 - .../config/external_connect_example.xml | 14 - .../config/external_equivalent_example.xml | 42 - gadgets/examples/config/external_example.xml | 42 - .../external_julia_acquisition_example.xml | 11 - .../external_matlab_acquisition_example.xml | 15 - .../config/external_matlab_bucket_example.xml | 28 - .../config/external_matlab_buffer_example.xml | 33 - .../config/external_matlab_tiny_example.xml | 33 - .../external_python_acquisition_example.xml | 10 - .../config/external_python_bucket_example.xml | 27 - .../config/external_python_buffer_example.xml | 33 - gadgets/fatwater/CMakeLists.txt | 32 - gadgets/fatwater/FatWaterGadget.cpp | 240 ----- gadgets/fatwater/FatWaterGadget.h | 58 -- .../Generic_Cartesian_Grappa_FatWater.xml | 270 ----- gadgets/hyper/CMRT.xml | 20 - gadgets/hyper/CMRT3D.xml | 27 - gadgets/hyper/CMRT3DGadget.cpp | 264 ----- gadgets/hyper/CMRT3DGadget.h | 46 - gadgets/hyper/CMRTGadget.cpp | 444 -------- gadgets/hyper/CMRTGadget.h | 81 -- gadgets/hyper/CMakeLists.txt | 37 - gadgets/hyper/CSIGadget.cpp | 297 ------ gadgets/hyper/CSIGadget.h | 69 -- gadgets/hyper/FS-CSI.xml | 79 -- gadgets/hyper/NFFT2D.xml | 18 - gadgets/hyper/NFFT2DGadget.cpp | 334 ------ gadgets/hyper/NFFT2DGadget.h | 56 - gadgets/hyper/gpuCSICoilEstimationGadget.cpp | 276 ----- gadgets/hyper/gpuCSICoilEstimationGadget.h | 59 -- gadgets/moco/CMakeLists.txt | 46 - gadgets/moco/RegistrationAveragingGadget.h | 271 ----- gadgets/moco/RegistrationScatteringGadget.h | 316 ------ gadgets/moco/config/CMakeLists.txt | 13 - .../config/cpureg_cartesian_averaging.xml | 95 -- .../config/gpureg_cartesian_averaging.xml | 95 -- .../moco/cpuRegistrationAveragingGadget.cpp | 44 - gadgets/moco/cpuRegistrationAveragingGadget.h | 24 - .../moco/gpuRegistrationAveragingGadget.cpp | 50 - gadgets/moco/gpuRegistrationAveragingGadget.h | 24 - .../moco/gpuRegistrationScatteringGadget.cpp | 57 - .../moco/gpuRegistrationScatteringGadget.h | 25 - gadgets/mri_core/CMakeLists.txt | 3 - ...ic_Cartesian_Grappa_RealTimeCine_Cloud.xml | 227 ---- ...an_NonLinear_Spirit_RealTimeCine_Cloud.xml | 255 ----- ...ng_NonLinear_Spirit_RealTimeCine_Cloud.xml | 255 ----- gadgets/mri_noncartesian/CMakeLists.txt | 62 -- .../CPUGriddingReconGadget.cpp | 31 - .../mri_noncartesian/CPUGriddingReconGadget.h | 24 - .../mri_noncartesian/GriddingReconGadget.cpp | 21 - .../mri_noncartesian/GriddingReconGadget.h | 17 - .../GriddingReconGadgetBase.h | 53 - .../GriddingReconGadgetBase.hpp | 293 ------ .../mri_noncartesian/NonCartesianTools.cpp | 134 --- gadgets/mri_noncartesian/NonCartesianTools.h | 8 - .../config/Generic_CPU_Gridding_Recon.xml | 111 -- .../config/Generic_Spiral.xml | 114 -- .../config/Generic_Spiral_Flag.xml | 113 -- .../config/Generic_Spiral_SNR.xml | 96 -- gadgets/plplot/CMakeLists.txt | 39 - .../Generic_Cartesian_Grappa_SNR_CoilQA.xml | 244 ----- .../plplot/NoiseCovariancePlottingGadget.cpp | 273 ----- .../plplot/NoiseCovariancePlottingGadget.h | 62 -- gadgets/python/CMakeLists.txt | 28 - ...c_Cartesian_Grappa_RealTimeCine_Python.xml | 214 ---- .../python/legacy/config/pseudoreplica.xml | 95 -- .../python/legacy/config/python_buckets.xml | 65 -- .../config/python_image_array_recon.xml | 64 -- .../legacy/config/python_passthrough.xml | 231 ----- gadgets/python/legacy/config/python_short.xml | 51 - .../legacy/gadgets/accumulate_and_recon.py | 79 -- gadgets/python/legacy/gadgets/bucket_recon.py | 67 -- .../legacy/gadgets/image_array_recon.py | 86 -- .../image_array_recon_rtcine_plotting.py | 155 --- gadgets/python/legacy/gadgets/passthrough.py | 13 - .../legacy/gadgets/passthrough_array_image.py | 32 - .../legacy/gadgets/pseudoreplicagather.py | 56 - .../legacy/gadgets/remove_2x_oversampling.py | 18 - .../python/legacy/gadgets/rms_coil_combine.py | 12 - test/e2e/conftest.py | 2 +- test/integration/README.md | 9 + test/integration/bart_cases/bart.cfg | 17 - toolboxes/CMakeLists.txt | 13 - toolboxes/T1/CMakeLists.txt | 36 - toolboxes/T1/t1fit.cpp | 606 ----------- toolboxes/T1/t1fit.h | 106 -- toolboxes/fatwater/CMakeLists.txt | 32 - toolboxes/fatwater/ImageGraph.cpp | 18 - toolboxes/fatwater/ImageGraph.h | 397 ------- toolboxes/fatwater/ImageGraph.hxx | 146 --- toolboxes/fatwater/bounded_field_map.cpp | 136 --- toolboxes/fatwater/bounded_field_map.h | 13 - .../fatwater/correct_frequency_shift.cpp | 84 -- toolboxes/fatwater/correct_frequency_shift.h | 16 - toolboxes/fatwater/fatwater.cpp | 661 ------------ toolboxes/fatwater/fatwater.h | 72 -- toolboxes/fatwater/graph_cut.cpp | 184 ---- toolboxes/fatwater/graph_cut.h | 13 - toolboxes/mri/hyper/CMRTOperator.cpp | 21 - toolboxes/mri/hyper/CMRTOperator.h | 144 --- toolboxes/mri/hyper/CSIOperator.cpp | 66 -- toolboxes/mri/hyper/CSIOperator.h | 44 - toolboxes/mri/hyper/CSI_utils.cu | 177 ---- toolboxes/mri/hyper/CSI_utils.h | 37 - toolboxes/mri/hyper/CSfreqOperator.h | 53 - toolboxes/plplot/CMakeLists.txt | 39 - toolboxes/plplot/GtPLplot.cpp | 654 ------------ toolboxes/plplot/GtPLplot.h | 53 - 145 files changed, 17 insertions(+), 16442 deletions(-) delete mode 100644 cmake/FindPLplot.cmake delete mode 100644 gadgets/T1/CMakeLists.txt delete mode 100644 gadgets/T1/T1MocoGadget.cpp delete mode 100644 gadgets/T1/config/MOLLI_T1_Moco.xml delete mode 100644 gadgets/bart/BART_Recon.xml delete mode 100644 gadgets/bart/BART_Recon_cloud.xml delete mode 100644 gadgets/bart/BART_Recon_cloud_Standard.xml delete mode 100644 gadgets/bart/CMakeLists.txt delete mode 100755 gadgets/bart/Sample_Grappa_Recon.sh delete mode 100755 gadgets/bart/Sample_Grappa_Recon_Standard.sh delete mode 100644 gadgets/bart/bart_helpers.cpp delete mode 100644 gadgets/bart/bart_helpers.h delete mode 100644 gadgets/bart/bart_logger.cpp delete mode 100644 gadgets/bart/bartgadget.cpp delete mode 100644 gadgets/bart/bartgadget.h delete mode 100644 gadgets/cartesian/CMakeLists.txt delete mode 100644 gadgets/cartesian/CartesianToGenericGadget.cpp delete mode 100644 gadgets/cartesian/CartesianToGenericGadget.h delete mode 100644 gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_Cloud.xml delete mode 100644 gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries_Cloud.xml delete mode 100644 gadgets/dicom/CMakeLists.txt delete mode 100644 gadgets/dicom/DicomFinishGadget.cpp delete mode 100644 gadgets/dicom/DicomFinishGadget.h delete mode 100644 gadgets/dicom/DicomImageWriter.cpp delete mode 100644 gadgets/dicom/DicomImageWriter.h delete mode 100644 gadgets/dicom/dicom.xml delete mode 100644 gadgets/dicom/dicom_ismrmrd_utility.cpp delete mode 100644 gadgets/dicom/dicom_ismrmrd_utility.h delete mode 100644 gadgets/examples/config/external_connect_example.xml delete mode 100644 gadgets/examples/config/external_equivalent_example.xml delete mode 100644 gadgets/examples/config/external_example.xml delete mode 100644 gadgets/examples/config/external_julia_acquisition_example.xml delete mode 100644 gadgets/examples/config/external_matlab_acquisition_example.xml delete mode 100644 gadgets/examples/config/external_matlab_bucket_example.xml delete mode 100644 gadgets/examples/config/external_matlab_buffer_example.xml delete mode 100644 gadgets/examples/config/external_matlab_tiny_example.xml delete mode 100644 gadgets/examples/config/external_python_acquisition_example.xml delete mode 100644 gadgets/examples/config/external_python_bucket_example.xml delete mode 100644 gadgets/examples/config/external_python_buffer_example.xml delete mode 100644 gadgets/fatwater/CMakeLists.txt delete mode 100644 gadgets/fatwater/FatWaterGadget.cpp delete mode 100644 gadgets/fatwater/FatWaterGadget.h delete mode 100644 gadgets/fatwater/config/Generic_Cartesian_Grappa_FatWater.xml delete mode 100644 gadgets/hyper/CMRT.xml delete mode 100644 gadgets/hyper/CMRT3D.xml delete mode 100644 gadgets/hyper/CMRT3DGadget.cpp delete mode 100644 gadgets/hyper/CMRT3DGadget.h delete mode 100644 gadgets/hyper/CMRTGadget.cpp delete mode 100644 gadgets/hyper/CMRTGadget.h delete mode 100644 gadgets/hyper/CMakeLists.txt delete mode 100644 gadgets/hyper/CSIGadget.cpp delete mode 100644 gadgets/hyper/CSIGadget.h delete mode 100644 gadgets/hyper/FS-CSI.xml delete mode 100644 gadgets/hyper/NFFT2D.xml delete mode 100644 gadgets/hyper/NFFT2DGadget.cpp delete mode 100644 gadgets/hyper/NFFT2DGadget.h delete mode 100644 gadgets/hyper/gpuCSICoilEstimationGadget.cpp delete mode 100644 gadgets/hyper/gpuCSICoilEstimationGadget.h delete mode 100644 gadgets/moco/CMakeLists.txt delete mode 100644 gadgets/moco/RegistrationAveragingGadget.h delete mode 100644 gadgets/moco/RegistrationScatteringGadget.h delete mode 100644 gadgets/moco/config/CMakeLists.txt delete mode 100644 gadgets/moco/config/cpureg_cartesian_averaging.xml delete mode 100644 gadgets/moco/config/gpureg_cartesian_averaging.xml delete mode 100644 gadgets/moco/cpuRegistrationAveragingGadget.cpp delete mode 100644 gadgets/moco/cpuRegistrationAveragingGadget.h delete mode 100644 gadgets/moco/gpuRegistrationAveragingGadget.cpp delete mode 100644 gadgets/moco/gpuRegistrationAveragingGadget.h delete mode 100644 gadgets/moco/gpuRegistrationScatteringGadget.cpp delete mode 100644 gadgets/moco/gpuRegistrationScatteringGadget.h delete mode 100644 gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine_Cloud.xml delete mode 100644 gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine_Cloud.xml delete mode 100644 gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine_Cloud.xml delete mode 100644 gadgets/mri_noncartesian/CMakeLists.txt delete mode 100644 gadgets/mri_noncartesian/CPUGriddingReconGadget.cpp delete mode 100644 gadgets/mri_noncartesian/CPUGriddingReconGadget.h delete mode 100644 gadgets/mri_noncartesian/GriddingReconGadget.cpp delete mode 100644 gadgets/mri_noncartesian/GriddingReconGadget.h delete mode 100644 gadgets/mri_noncartesian/GriddingReconGadgetBase.h delete mode 100644 gadgets/mri_noncartesian/GriddingReconGadgetBase.hpp delete mode 100644 gadgets/mri_noncartesian/NonCartesianTools.cpp delete mode 100644 gadgets/mri_noncartesian/NonCartesianTools.h delete mode 100644 gadgets/mri_noncartesian/config/Generic_CPU_Gridding_Recon.xml delete mode 100644 gadgets/mri_noncartesian/config/Generic_Spiral.xml delete mode 100644 gadgets/mri_noncartesian/config/Generic_Spiral_Flag.xml delete mode 100644 gadgets/mri_noncartesian/config/Generic_Spiral_SNR.xml delete mode 100644 gadgets/plplot/CMakeLists.txt delete mode 100644 gadgets/plplot/Generic_Cartesian_Grappa_SNR_CoilQA.xml delete mode 100644 gadgets/plplot/NoiseCovariancePlottingGadget.cpp delete mode 100644 gadgets/plplot/NoiseCovariancePlottingGadget.h delete mode 100644 gadgets/python/CMakeLists.txt delete mode 100644 gadgets/python/config/Generic_Cartesian_Grappa_RealTimeCine_Python.xml delete mode 100644 gadgets/python/legacy/config/pseudoreplica.xml delete mode 100644 gadgets/python/legacy/config/python_buckets.xml delete mode 100644 gadgets/python/legacy/config/python_image_array_recon.xml delete mode 100644 gadgets/python/legacy/config/python_passthrough.xml delete mode 100644 gadgets/python/legacy/config/python_short.xml delete mode 100644 gadgets/python/legacy/gadgets/accumulate_and_recon.py delete mode 100644 gadgets/python/legacy/gadgets/bucket_recon.py delete mode 100644 gadgets/python/legacy/gadgets/image_array_recon.py delete mode 100644 gadgets/python/legacy/gadgets/image_array_recon_rtcine_plotting.py delete mode 100644 gadgets/python/legacy/gadgets/passthrough.py delete mode 100644 gadgets/python/legacy/gadgets/passthrough_array_image.py delete mode 100644 gadgets/python/legacy/gadgets/pseudoreplicagather.py delete mode 100644 gadgets/python/legacy/gadgets/remove_2x_oversampling.py delete mode 100644 gadgets/python/legacy/gadgets/rms_coil_combine.py create mode 100644 test/integration/README.md delete mode 100644 test/integration/bart_cases/bart.cfg delete mode 100644 toolboxes/T1/CMakeLists.txt delete mode 100644 toolboxes/T1/t1fit.cpp delete mode 100644 toolboxes/T1/t1fit.h delete mode 100644 toolboxes/fatwater/CMakeLists.txt delete mode 100644 toolboxes/fatwater/ImageGraph.cpp delete mode 100644 toolboxes/fatwater/ImageGraph.h delete mode 100644 toolboxes/fatwater/ImageGraph.hxx delete mode 100644 toolboxes/fatwater/bounded_field_map.cpp delete mode 100644 toolboxes/fatwater/bounded_field_map.h delete mode 100644 toolboxes/fatwater/correct_frequency_shift.cpp delete mode 100644 toolboxes/fatwater/correct_frequency_shift.h delete mode 100644 toolboxes/fatwater/fatwater.cpp delete mode 100644 toolboxes/fatwater/fatwater.h delete mode 100644 toolboxes/fatwater/graph_cut.cpp delete mode 100644 toolboxes/fatwater/graph_cut.h delete mode 100644 toolboxes/mri/hyper/CMRTOperator.cpp delete mode 100644 toolboxes/mri/hyper/CMRTOperator.h delete mode 100644 toolboxes/mri/hyper/CSIOperator.cpp delete mode 100644 toolboxes/mri/hyper/CSIOperator.h delete mode 100644 toolboxes/mri/hyper/CSI_utils.cu delete mode 100644 toolboxes/mri/hyper/CSI_utils.h delete mode 100644 toolboxes/mri/hyper/CSfreqOperator.h delete mode 100644 toolboxes/plplot/CMakeLists.txt delete mode 100644 toolboxes/plplot/GtPLplot.cpp delete mode 100644 toolboxes/plplot/GtPLplot.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bdfea17c1..76a50a4d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,9 +48,9 @@ else () endif () #VERSIONING AND INSTALL PATHS -set(PINGVIN_VERSION_MAJOR 5) -set(PINGVIN_VERSION_MINOR 0) -set(PINGVIN_VERSION_PATCH 0.alpha.1) +set(PINGVIN_VERSION_MAJOR 0) +set(PINGVIN_VERSION_MINOR 1) +set(PINGVIN_VERSION_PATCH 0) set(PINGVIN_VERSION_STRING ${PINGVIN_VERSION_MAJOR}.${PINGVIN_VERSION_MINOR}.${PINGVIN_VERSION_PATCH}) set(PINGVIN_SOVERSION ${PINGVIN_VERSION_MAJOR}.${PINGVIN_VERSION_MINOR}) find_package(Git) @@ -217,11 +217,6 @@ install(TARGETS armadillo EXPORT pingvin-export) add_subdirectory(libmrd) -if (CUDA_FOUND AND USE_CUDA) - # bart needs cuda - find_package(BART CONFIG QUIET) -endif() - find_package(FFTW3 REQUIRED COMPONENTS single double) add_library(FFTW INTERFACE) target_link_libraries(FFTW INTERFACE ${FFTW3_LIBRARIES}) @@ -294,8 +289,6 @@ if (BUILD_PYTHON_SUPPORT) install(TARGETS python EXPORT pingvin-export) endif() -find_package(PLplot) - option(BUILD_TESTING "Enable test building" On) if (BUILD_TESTING) enable_testing() diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 84641aa93..1529fea41 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -5,7 +5,6 @@ install(FILES FindGperftools.cmake FindMKL.cmake FindOctave.cmake - FindPLplot.cmake FindCBLAS.cmake FindLAPACKE.cmake FindPugiXML.cmake diff --git a/cmake/FindPLplot.cmake b/cmake/FindPLplot.cmake deleted file mode 100644 index e01f7f861..000000000 --- a/cmake/FindPLplot.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# - Find the PLplot libraries -# This module defines -# PLPLOT_INCLUDE_DIR, the directory for the PLplot headers -# PLPLOT_LIB_DIR, the directory for the PLplot library files -# PLPLOT_LIBRARIES, the libraries needed to use PLplot. -# PLPLOT_FOUND, If false, do not try to use PLplot; if true, the macro definition USE_PLPLOT is added. - -if (WIN32) - if (NOT DEFINED ENV{PLPLOT_PATH}) - set(PLPLOT_PATH "C:/Program Files" CACHE PATH "Where the PLplot are stored") - endif () -else () - set(PLPLOT_PATH $ENV{CONDA_PREFIX}/include CACHE PATH "Where the PLplot are stored") - message("PLPLOT_PATH is ${PLPLOT_PATH}") -endif () - -if (EXISTS ${PLPLOT_PATH}/plplot) - set(PLPLOT_FOUND TRUE) - message("PLplot is found at ${PLPLOT_PATH}/plplot") -else () - set(PLPLOT_FOUND FALSE) - message("PLplot is NOT found ... ") -endif () - -if (PLPLOT_FOUND) - if (WIN32) - set(PLPLOT_INCLUDE_DIR "${PLPLOT_PATH}/plplot") - set(PLPLOT_LIB_DIR "${PLPLOT_PATH}/../lib") - set(PLPLOT_LIBRARIES plplot) - set(PLPLOT_LIBRARIES ${PLPLOT_LIBRARIES} plplotcxx) - else () - set(PLPLOT_INCLUDE_DIR "${PLPLOT_PATH}/plplot") - set(PLPLOT_LIB_DIR "${PLPLOT_PATH}/../lib") - - find_library(PLPLOT_LIB - NAMES plplot plplotd - HINTS /usr/lib /usr/lib64 /usr/x86_64-linux-gnu) - - find_library(PLPLOT_CXX_LIB - NAMES plplotcxx plplotcxxd - HINTS /usr/lib /usr/lib64 /usr/x86_64-linux-gnu) - - set(PLPLOT_LIBRARIES ${PLPLOT_LIB} ${PLPLOT_CXX_LIB}) - - message("PLplot libraries: ${PLPLOT_LIBRARIES}") - endif () - - add_definitions(-DUSE_PLPLOT) - -endif () diff --git a/conda/meta.yaml b/conda/meta.yaml index de2959fa4..ed2dbed09 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -18,7 +18,6 @@ requirements: - cuda-libraries=12.3.0 # [linux64] - cuda-nvcc=12.3.52 # [linux64] - cuda-runtime=12.3.0 # [linux64] - - dcmtk=3.6.1 - fftw=3.3.9 - gcc_linux-64=9.4.0 # [linux64] - gmock=1.14.0 @@ -53,7 +52,6 @@ requirements: - boost=1.80.0 - cuda-libraries=12.3.0 # [linux64] - cuda-runtime=12.3.0 # [linux64] - - dcmtk=3.6.1 - fftw=3.3.9 - h5py=3.7.0 - hdf5=1.10.6 diff --git a/doc/source/conf.py b/doc/source/conf.py index dcde2c22d..989d9470d 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -43,10 +43,10 @@ def configureDoxyfile(input_dir, output_dir): project = 'Pingvin' copyright = '2024 Gadgetron' -author = 'Gadgetron Developers' +author = 'Pingvin Developers' # The full version, including alpha/beta/rc tags -release = '4.0' +release = '0.1.0' # -- General configuration --------------------------------------------------- diff --git a/doc/source/using.md b/doc/source/using.md index 13f012782..a41029626 100644 --- a/doc/source/using.md +++ b/doc/source/using.md @@ -100,16 +100,3 @@ instance a chain which produces complex images can be converted to float images, ```bash mrd_phantom | pingvin -c Generic_Cartesian_Grappa_Complex.xml | pingvin -c stream_complex_to_float.xml | pingvin -c stream_float_to_short.xml -o reconstructed.mrd ``` - -#### Using ISMRMRD input - -MR data in the ISMRMRD format must be converted to MRDv2 for compatibility with Pingvin. - -You can use the MRD <-> ISMRMRD HDF5/Stream conversion tools (or adapters) *inline* with Pingvin. -Example: - -```bash -ismrmrd_generate_cartesian_shepp_logan -r 10 -o testdata.h5 - -ismrmrd_hdf5_to_stream -i testdata.h5 --use-stdout | ismrmrd_to_mrd | pingvin -c default.xml | mrd_to_ismrmrd | ismrmrd_stream_to_hdf5 --use-stdin -o reconstructed.h5 -``` diff --git a/environment.yml b/environment.yml index 03f5633a7..9adeff126 100644 --- a/environment.yml +++ b/environment.yml @@ -24,7 +24,6 @@ dependencies: - cuda-nvrtc=12.3.52 # cuda - cuda-nvrtc-dev=12.3.52 # cuda, dev - cuda-runtime=12.3.0 # cuda - - dcmtk=3.6.1 - deepdiff=7.0.1 - doxygen=1.10.0 # dev - eigen=3.4.0 @@ -60,7 +59,6 @@ dependencies: - onnxruntime=1.18.1 - packaging=24.0 - pip=24.0 # dev - - plplot=5.15.0 - pugixml=1.12.1 - pyfftw=0.13.1 - pytest=8.3.3 diff --git a/gadgets/CMakeLists.txt b/gadgets/CMakeLists.txt index 39fc27cd2..b50a74952 100644 --- a/gadgets/CMakeLists.txt +++ b/gadgets/CMakeLists.txt @@ -6,7 +6,6 @@ add_subdirectory(cmr) add_subdirectory(epi) add_subdirectory(spiral) add_subdirectory(grappa) -add_subdirectory(python) if (CUDA_FOUND) message("Cuda found, compiling gpu accelerated gadgets") @@ -15,37 +14,4 @@ if (CUDA_FOUND) add_subdirectory(gpu) else () message("Cuda NOT found, NOT compiling gpu accelerated gadgets") -endif() - - -# NOTE: -# The remaining gadgets directories below are NOT TESTED and have not yet been upgraded to MRD v2. - -# add_subdirectory(fatwater) -# add_subdirectory(T1) -# add_subdirectory(mri_noncartesian) -# add_subdirectory(cartesian) -# add_subdirectory(moco) - -# if(BART_FOUND) -# add_subdirectory(bart) -# else() -# message("BART not found, NOT compiling bartgadget") -# endif() - -# if (CUDA_FOUND) -# add_subdirectory(hyper) -# endif() - -# find_package(DCMTK CONFIG) -# if(DCMTK_FOUND) -# add_subdirectory(dicom) -# else() -# message("DCMTK NOT found, not compiling DICOM gadget") -# endif() - -# if(PLPLOT_FOUND) -# if (MKL_FOUND OR ARMADILLO_FOUND) -# add_subdirectory(plplot) -# endif () -# endif() \ No newline at end of file +endif() \ No newline at end of file diff --git a/gadgets/T1/CMakeLists.txt b/gadgets/T1/CMakeLists.txt deleted file mode 100644 index db03a6574..000000000 --- a/gadgets/T1/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ - -set(pingvin_t1_config_files config/MOLLI_T1_Moco.xml) - -source_group(config FILES ${pingvin_t1_config_files}) - -add_library(pingvin_t1 SHARED - T1MocoGadget.cpp) - -set_target_properties(pingvin_t1 PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_t1 - pingvin_core - pingvin_toolbox_log - pingvin_toolbox_cpucore - pingvin_toolbox_cpufft - pingvin_toolbox_demons - pingvin_toolbox_t1 - pingvin_toolbox_mri_core -) - -install(TARGETS pingvin_t1 - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install(FILES ${pingvin_t1_config_files} DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) diff --git a/gadgets/T1/T1MocoGadget.cpp b/gadgets/T1/T1MocoGadget.cpp deleted file mode 100644 index 50b211cba..000000000 --- a/gadgets/T1/T1MocoGadget.cpp +++ /dev/null @@ -1,381 +0,0 @@ -// -// Created by dchansen on 3/9/20. -// -#include "demons_registration.h" -#include - -#include "PureGadget.h" -#include "cmr_parametric_mapping.h" -#include "hoNDArray_fileio.h" -#include "hoNDArray_math.h" -#include "hoNDArray_utils.h" -#include "mri_core_def.h" -#include "t1fit.h" -#include -#include -namespace Gadgetron { - -class T1MocoGadget : public Core::ChannelGadget { - - public: - T1MocoGadget(const Core::Context& context, const Core::GadgetProperties& properties) - : Core::ChannelGadget(context, properties), - field_strength{*context.header.acquisitionSystemInformation->systemFieldStrength_T} {} - - NODE_PROPERTY(correction_factor, float, "Empirical correction factor for T1", 1.0365f); - NODE_PROPERTY(regularization_sigma, float, "Gaussian regularizatin for registration", 2.0f); - NODE_PROPERTY(demons_iterations, unsigned int, "Number of iterations for the demons registration", 40); - NODE_PROPERTY(step_size, float, "Maximum step size for demons registration (between 0.1 and 2.0)", 2.0f); - NODE_PROPERTY(iterations, unsigned int, "Number of iterations of demons registration and T1 fit", 5); - NODE_PROPERTY(scales, unsigned int, "Number of image scales to use", 1); - - private: - void process(Core::InputChannel& input, Core::OutputChannel& out) final override { - - GDEBUG("Sigma %f demons_iterations %i Step size %f iterations %i\n", regularization_sigma, demons_iterations, - step_size, iterations); - - for (auto images : input) { - - auto TI_values = extract_MOLLI_TI(*images.acq_headers_); - auto data_dims = images.data_.dimensions(); - images.data_.reshape(data_dims[0], data_dims[1], -1); - - sort_images_and_values(images, TI_values); - - auto moco_images = multi_stage_T1_registration(images.data_, TI_values); - - auto phase_corrected = T1::phase_correct(moco_images, TI_values); - - const auto [A, B, T1star] = T1::fit_T1_3param(phase_corrected, TI_values); - - auto T1 = t1_from_t1star(A, B, T1star); - clean_image(T1); - perform_hole_filling(T1); - - auto error_map = T1::calculate_error_map({A, B, T1}, phase_corrected, TI_values); - clean_image(error_map,1000); - - T1 *= correction_factor; - - auto header = images.headers_[0]; - header.data_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; - header.image_series_index = 5; - auto meta = create_T1_meta(images.meta_.front(),T1); - auto sd_meta = create_T1SD_meta(images.meta_.front()); - // send original images - images.data_.reshape(data_dims); - set_RAW_headers_and_meta(images, TI_values); - out.push(images); - - // send MOCO images - images.data_ = hoNDArray>(phase_corrected); - images.data_.reshape(data_dims); - - auto mag_images = images; - mag_images.data_ = hoNDArray>(abs(moco_images)); - mag_images.data_.reshape(data_dims); - set_MOCO_MAG_headers_and_meta(mag_images, TI_values); - out.push(std::move(mag_images)); - - set_PSIR_headers_and_meta(images, TI_values); - out.push(std::move(images)); - - // send out T1 map - auto sd_header = header; - sd_header.image_series_index = 4; - out.push(mrd::Image{sd_header, std::move(error_map), sd_meta}); - out.push(mrd::Image{header, std::move(T1), meta}); - } - } - - ISMRMRD::MetaContainer create_T1SD_meta(ISMRMRD::MetaContainer meta) const { - - double scaling_factor = 1; - double window_center = 200; - double window_width = 400; - std::string lut = - std::abs(field_strength - float(1.5)) < 1e-1 ? "GadgetronT1_IR_1_5T.pal" : "GadgetronT1_IR_3T.pal"; - - std::ostringstream ostr; - ostr << "x" << scaling_factor; - std::string scalingStr = ostr.str(); - - std::ostringstream ostr_unit; - ostr_unit << std::setprecision(3) << 1.0f / scaling_factor << "ms"; - std::string unitStr = ostr_unit.str(); - - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_T1SDMAP); - meta.append(GADGETRON_SEQUENCEDESCRIPTION, GADGETRON_IMAGE_T1SDMAP); - meta.append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_MOCO); - meta.append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_T1SDMAP); - - meta.set(GADGETRON_IMAGE_SCALE_RATIO, scaling_factor); - meta.set(GADGETRON_IMAGE_WINDOWCENTER, (long)(window_center * scaling_factor)); - meta.set(GADGETRON_IMAGE_WINDOWWIDTH, (long)(window_width * scaling_factor)); - meta.set(GADGETRON_IMAGE_COLORMAP, lut.c_str()); - - meta.set(GADGETRON_IMAGECOMMENT, meta.as_str(GADGETRON_DATA_ROLE)); - meta.append(GADGETRON_IMAGECOMMENT, scalingStr.c_str()); - meta.append(GADGETRON_IMAGECOMMENT, unitStr.c_str()); - - return std::move(meta); - } - - static std::pair find_window_center_width_T1(const hoNDArray& image, const ISMRMRD::IsmrmrdHeader& header ){ - - std::pair pre_window = {1300,1300}; - std::pair post_window = {400,300}; - - try { - auto protocolname = header.measurementInformation.get().protocolName.get(); - - std::regex is_post(R"((?:^|[^A-Z])post(?:$|[^A-Z]))", std::regex_constants::icase | std::regex_constants::ECMAScript); - if (std::regex_search(protocolname,is_post)) return post_window; - - std::regex is_pre(R"((?:^|[^A-Z])pre(?:$|[^A-Z]))", std::regex_constants::icase | std::regex_constants::ECMAScript); - if (std::regex_search(protocolname,is_pre)) return pre_window; - - } catch (...) {} - - - auto top = percentile(image, 0.9f); - - auto window_distance = [top](const auto& window){ return (top - ( window.first+window.second/2));}; - - if (window_distance(pre_window) < window_distance(post_window)) - return pre_window; - else - return post_window; - } - - ISMRMRD::MetaContainer create_T1_meta(ISMRMRD::MetaContainer meta, const hoNDArray& t1map) const { - - double scaling_factor = 1; - - auto [window_center, window_width] = find_window_center_width_T1(t1map,header); - GDEBUG("Setting T1 window level to %f %f \n", window_center, window_width); - - std::string lut = - std::abs(field_strength - float(1.5)) < 1e-1 ? "GadgetronT1_IR_1_5T.pal" : "GadgetronT1_IR_3T.pal"; - - std::ostringstream ostr; - ostr << "x" << scaling_factor; - std::string scalingStr = ostr.str(); - - std::ostringstream ostr_unit; - ostr_unit << std::setprecision(3) << 1.0f / scaling_factor << "ms"; - std::string unitStr = ostr_unit.str(); - - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_T1MAP); - meta.append(GADGETRON_SEQUENCEDESCRIPTION, GADGETRON_IMAGE_T1MAP); - meta.append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_MOCO); - meta.append(GADGETRON_IMAGEPROCESSINGHISTORY, GADGETRON_IMAGE_T1MAP); - - meta.set(GADGETRON_IMAGE_SCALE_RATIO, scaling_factor); - meta.set(GADGETRON_IMAGE_WINDOWCENTER, (long)(window_center * scaling_factor)); - meta.set(GADGETRON_IMAGE_WINDOWWIDTH, (long)(window_width * scaling_factor)); - meta.set(GADGETRON_IMAGE_COLORMAP, lut.c_str()); - - meta.set(GADGETRON_IMAGECOMMENT, meta.as_str(GADGETRON_DATA_ROLE)); - meta.append(GADGETRON_IMAGECOMMENT, scalingStr.c_str()); - meta.append(GADGETRON_IMAGECOMMENT, unitStr.c_str()); - - return std::move(meta); - } - - static std::vector extract_MOLLI_TI(const hoNDArray& acq_headers) { - - std::map> look_locker_sets; - - for (auto subarray : spans(acq_headers, 1)) { - auto& header = *std::find_if(subarray.begin(), subarray.end(), [](ISMRMRD::AcquisitionHeader& acq_header) { - return acq_header.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_SLICE); - }); - look_locker_sets[header.user_int[5]].push_back(header); - } - - std::vector TI_values; - - for (auto& [set, headers] : look_locker_sets) { - auto minimum_acquisition_time_stamp = std::accumulate( - headers.begin(), headers.end(), std::numeric_limits::max(), [](auto val1, auto val2) { - return val1 < val2.acquisition_time_stamp ? val1 : val2.acquisition_time_stamp; - }); - - for (auto& header : headers) { - float TI_value = - (header.acquisition_time_stamp - minimum_acquisition_time_stamp) * 2.5f + header.user_int[4]; - TI_values.push_back(TI_value); - GDEBUG("set %d look-locker %d ti: %f acq_time_stamp: %d \n", header.idx.set, set, TI_value, - header.acquisition_time_stamp); - } - } - - return TI_values; - } - - static void clean_image(hoNDArray& data, float upper_limit = 5000.0f) { - std::transform(data.begin(), data.end(), data.begin(), [upper_limit](auto val) { - if (val <= 0) - return 0.0f; - if (val >= upper_limit) - return 0.0f; - if (std::isnan(val)) - return 0.0f; - return val; - }); - } - - void sort_images_and_values(IsmrmrdImageArray& images, std::vector& TI_values) { - auto sorted_index = argsort(TI_values); - - auto dims = images.data_.dimensions(); - images.data_.reshape(dims[0], dims[1], -1); - auto data_copy = images.data_; - std::fill(images.data_.begin(), images.data_.end(), std::complex(1)); - - for (size_t i = 0; i < data_copy.get_size(2); i++) { - using namespace Gadgetron::Indexing; - images.data_(slice, slice, i) = data_copy(slice, slice, sorted_index[i]); - } - images.data_.reshape(dims); - - auto TI_sorted = TI_values; - - for (size_t i = 0; i < TI_values.size(); i++) - TI_sorted[i] = TI_values[sorted_index[i]]; - - TI_values = std::move(TI_sorted); - } - static void set_RAW_headers_and_meta(IsmrmrdImageArray& images, const std::vector& TI_values) { - for (auto& header : images.headers_) { - header.image_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; - header.image_series_index = 1; - } - - for (size_t ind = 0; ind < images.meta_.size(); ind++) { - auto& meta = images.meta_[ind]; - meta.set(GADGETRON_IMAGE_INVERSIONTIME, (double)(TI_values[ind])); - } - } - - static void set_MOCO_MAG_headers_and_meta(IsmrmrdImageArray& images, const std::vector& TI_values) { - for (auto& header : images.headers_) { - header.image_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; - header.image_series_index = 2; - } - - for (size_t ind = 0; ind < images.meta_.size(); ind++) { - auto& meta = images.meta_[ind]; - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_MOCO); - meta.set(GADGETRON_IMAGE_INVERSIONTIME, (double)(TI_values[ind])); - meta.append(GADGETRON_SEQUENCEDESCRIPTION,GADGETRON_IMAGE_MOCO); - } - } - - static void set_PSIR_headers_and_meta(IsmrmrdImageArray& images, const std::vector& TI_values) { - for (auto& header : images.headers_) { - header.image_type = ISMRMRD::ISMRMRD_IMTYPE_REAL; - header.image_series_index = 3; - } - - images.data_ += 4096.0; - for (size_t ind = 0; ind < images.meta_.size(); ind++) { - auto& meta = images.meta_[ind]; - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_PSIR); - meta.append(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_MOCO); - meta.set(GADGETRON_IMAGE_SCALE_OFFSET, (double)(4096.0)); - meta.set(GADGETRON_IMAGE_INVERSIONTIME, (double)(TI_values[ind])); - meta.append(GADGETRON_SEQUENCEDESCRIPTION,GADGETRON_IMAGE_MOCO); - meta.append(GADGETRON_SEQUENCEDESCRIPTION,GADGETRON_IMAGE_PSIR); - } - } - - template std::vector argsort(const std::vector& data) { - - std::vector> index_and_values(data.size()); - - for (size_t i = 0; i < data.size(); i++) - index_and_values[i] = {i, data[i]}; - - std::stable_sort(index_and_values.begin(), index_and_values.end(), - [](auto val1, auto val2) { return val1.second < val2.second; }); - - std::vector index(data.size()); - - for (size_t i = 0; i < data.size(); i++) - index[i] = index_and_values[i].first; - return index; - } - - hoNDArray> multi_stage_T1_registration(const hoNDArray>& data, - const std::vector& TIs) const { - - auto abs_data = abs(data); - auto first_vfields = register_compatible_frames(abs_data, TIs); - auto second_vfields = T1::t1_registration(data, TIs, std::move(first_vfields), iterations, - {demons_iterations, regularization_sigma, step_size}); - - auto deformed_images = T1::deform_groups(abs_data, second_vfields); - auto final_vfield = T1::register_groups_CMR(abs_data, deformed_images, 24.0f); - return T1::deform_groups(data, final_vfield); - } - - hoNDArray> register_compatible_frames(const hoNDArray& abs_data, - const std::vector& TIs) const { - using namespace Gadgetron::Indexing; - using namespace ranges; - auto arg_max_TI = max_element(TIs) - TIs.begin(); - - const hoNDArray reference_frame = abs_data(slice, slice, arg_max_TI); - - const auto valid_transforms = - views::iota(size_t(0), abs_data.get_size(2)) | - views::filter([&arg_max_TI](auto index) { return index != arg_max_TI; }) | views::filter([&](auto index) { - return jensen_shannon_divergence(abs_data(slice, slice, index), reference_frame) < 0.2; - }) | - to(); - - std::vector>> vfields(abs_data.get_size(2)); - -#pragma omp parallel for default(shared) - for (int i = 0; i < int(valid_transforms.size()); i++) { - vfields[valid_transforms[i]] = - T1::register_groups_CMR(abs_data(slice, slice, valid_transforms[i]), reference_frame); - } - auto missing_indices = views::iota(size_t(0), abs_data.get_size(2)) | views::filter([&](auto index) { - return !binary_search(valid_transforms, index) && (index != arg_max_TI); - }); - - for (auto index : missing_indices) { - auto closest_index = lower_bound(valid_transforms, index); - if (closest_index != valid_transforms.end()) { - vfields[index] = vfields[*closest_index]; - } else { - vfields[index] = hoNDArray>(abs_data.get_size(0), abs_data.get_size(1), 1); - vfields[index].fill(vector_td(0, 0)); - } - } - - vfields[arg_max_TI] = hoNDArray>(abs_data.get_size(0), abs_data.get_size(1), 1); - vfields[arg_max_TI].fill(vector_td(0, 0)); - return concat_along_dimension(vfields, 2); - } - - hoNDArray t1_from_t1star(const hoNDArray& A, const hoNDArray& B, - const hoNDArray& T1star) { - - auto T1 = hoNDArray(T1star.dimensions()); - - for (size_t i = 0; i < T1.size(); i++) - T1[i] = T1star[i] * (B[i] / A[i] - 1.0f); - - return T1; - } - - float field_strength; -}; - -GADGETRON_GADGET_EXPORT(T1MocoGadget) -} // namespace Gadgetron diff --git a/gadgets/T1/config/MOLLI_T1_Moco.xml b/gadgets/T1/config/MOLLI_T1_Moco.xml deleted file mode 100644 index d0da31aa1..000000000 --- a/gadgets/T1/config/MOLLI_T1_Moco.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - 2 - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionset - S_dimensioncontrast - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Strue - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosefalse - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres0.002 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressionfalse - downstream_coil_compression_thres0.01 - downstream_coil_compression_num_modesKept0 - - - debug_folder - perform_timingtrue - verbosetrue - - - send_out_gfactorfalse - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.5 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.5 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.5 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - T1Gadget - pingvin_t1 - T1MocoGadget - - - - - - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - max_intensity32767 - min_intensity0 - intensity_offset0 - - - - diff --git a/gadgets/bart/BART_Recon.xml b/gadgets/bart/BART_Recon.xml deleted file mode 100644 index 94ff2f2c9..000000000 --- a/gadgets/bart/BART_Recon.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaystrue - - - - - bartgadget - pingvin_bart - BartGadget - isVerboseONtrue - BartCommandScript_nameSample_Grappa_Recon.sh - - - isBartFileBeingStoredfalse - image_series0 - - BartFileBehaviourBART_MIX_DISK_MEM - - BartStoreGadgetronInputInMemoryfalse - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - debug_folder - perform_timingfalse - verbosetrue - - skip_processing_meta_fieldSkip_processing_after_recon - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - debug_folder - perform_timingfalse - verbosefalse - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/bart/BART_Recon_cloud.xml b/gadgets/bart/BART_Recon_cloud.xml deleted file mode 100644 index 29236fa8c..000000000 --- a/gadgets/bart/BART_Recon_cloud.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaystrue - - - - - bartgadget - pingvin_bart - BartGadget - isVerboseONfalse - BartCommandScript_nameSample_Grappa_Recon.sh - - - isBartFileBeingStoredfalse - image_series0 - - BartFileBehaviourBART_MIX_DISK_MEM - - BartStoreGadgetronInputInMemoryfalse - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - debug_folder - perform_timingfalse - verbosetrue - skip_processing_meta_fieldSkip_processing_after_recon - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - debug_folder - perform_timingfalse - verbosefalse - skip_processing_meta_fieldSkip_processing_after_recon - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - | - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - debug_folder - perform_timingfalse - verbosefalse - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - - Sort - pingvin_mricore - ImageSortGadget - - sorting_dimension - repetition - - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/bart/BART_Recon_cloud_Standard.xml b/gadgets/bart/BART_Recon_cloud_Standard.xml deleted file mode 100644 index fd61d58f3..000000000 --- a/gadgets/bart/BART_Recon_cloud_Standard.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaystrue - - - - - bartgadget - pingvin_bart - BartGadget - isVerboseONfalse - BartCommandScript_nameSample_Grappa_Recon_Standard.sh - - - isBartFileBeingStoredfalse - image_series0 - - BartFileBehaviourBART_MIX_DISK_MEM - - BartStoreGadgetronInputInMemoryfalse - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - debug_folder - perform_timingfalse - verbosetrue - skip_processing_meta_fieldSkip_processing_after_recon - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - debug_folder - perform_timingfalse - verbosefalse - skip_processing_meta_fieldSkip_processing_after_recon - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - | - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - debug_folder - perform_timingfalse - verbosefalse - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - - Sort - pingvin_mricore - ImageSortGadget - - sorting_dimension - repetition - - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/bart/CMakeLists.txt b/gadgets/bart/CMakeLists.txt deleted file mode 100644 index b0b92823c..000000000 --- a/gadgets/bart/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -cmake_policy(SET CMP0028 NEW) # double colon only for imported or alias libraries - -# ============================================================================== -# First try to find either the BARTmain library or a path to the BART source code - -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake) - - -# ============================================================================== - -set(GADGET_FILES - bartgadget.h - bartgadget.cpp - bart_helpers.h - bart_helpers.cpp - bart_logger.cpp - BART_Recon.xml - BART_Recon_cloud.xml - BART_Recon_cloud_Standard.xml -) - -# ------------------------------------------------------------------------------ - -if(BART_MEMONLY_CFL) - add_definitions(-DMEMONLY_CFL) -endif() - -add_library(pingvin_bart SHARED ${GADGET_FILES}) -target_link_libraries(pingvin_bart BART::BARTMAIN) - - - -set_target_properties(pingvin_bart - PROPERTIES - VERSION ${PINGVIN_VERSION_STRING} - SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_bart pingvin_core - pingvin_mricore - pingvin_toolbox_mri_core - pingvin_toolbox_log - pingvin_toolbox_cpucore - pingvin_toolbox_cpufft - pingvin_toolbox_cpuklt - ) - - target_link_libraries(pingvin_bart pingvin_toolbox_cpucore_math) - -install(FILES bartgadget.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - - install(TARGETS pingvin_bart - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -set(PINGVIN_INSTALL_BART_PATH share/pingvin/bart) -install(FILES Sample_Grappa_Recon.sh Sample_Grappa_Recon_Standard.sh DESTINATION ${PINGVIN_INSTALL_BART_PATH}) - -install(FILES BART_Recon.xml BART_Recon_cloud.xml BART_Recon_cloud_Standard.xml DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/bart/Sample_Grappa_Recon.sh b/gadgets/bart/Sample_Grappa_Recon.sh deleted file mode 100755 index fb6e633c9..000000000 --- a/gadgets/bart/Sample_Grappa_Recon.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# List of available default parameters -# recon_matrix_x; -# recon_matrix_y; -# recon_matrix_z; -# FOV_x; -# FOV_y; -# FOV_z; -# acc_factor_PE1; -# acc_factor_PE2; -# reference_lines_PE1; -# reference_lines_PE2; -# input_data; -# reference_data; -# traj_data; - -debug=false - -if "$debug"; then - set -x -fi - -# Those two lines will be ignored by the BartGadget but allow you to execute -# the script outside of Gadgetron with little changes -# Possible inputs provided by the BartGadget are: -# - $reference_data -# - $input_data -# - $traj_data - -input_data="path/to/a/file" -reference_data="path/to/another/file" - -bart cc -S $reference_data cc_mat -# Compress coils to 12 virtual channels -bart extract 4 0 11 cc_mat cc_mat_P - -bart fmac -C -s 8 $reference_data cc_mat_P reference_data_cc -bart transpose 3 4 reference_data_cc cc_reference_data - -bart fmac -C -s 8 $input_data cc_mat_P input_data_cc -bart transpose 3 4 input_data_cc cc_input_data - -bart ecalib -c0.7 -k7 -r$reference_lines_PE1 -m4 -S cc_reference_data maps -bart pics -l1 -r0.1 -i150 cc_input_data maps ims - -if "$debug";then - set +x -fi diff --git a/gadgets/bart/Sample_Grappa_Recon_Standard.sh b/gadgets/bart/Sample_Grappa_Recon_Standard.sh deleted file mode 100755 index fb6e633c9..000000000 --- a/gadgets/bart/Sample_Grappa_Recon_Standard.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -# List of available default parameters -# recon_matrix_x; -# recon_matrix_y; -# recon_matrix_z; -# FOV_x; -# FOV_y; -# FOV_z; -# acc_factor_PE1; -# acc_factor_PE2; -# reference_lines_PE1; -# reference_lines_PE2; -# input_data; -# reference_data; -# traj_data; - -debug=false - -if "$debug"; then - set -x -fi - -# Those two lines will be ignored by the BartGadget but allow you to execute -# the script outside of Gadgetron with little changes -# Possible inputs provided by the BartGadget are: -# - $reference_data -# - $input_data -# - $traj_data - -input_data="path/to/a/file" -reference_data="path/to/another/file" - -bart cc -S $reference_data cc_mat -# Compress coils to 12 virtual channels -bart extract 4 0 11 cc_mat cc_mat_P - -bart fmac -C -s 8 $reference_data cc_mat_P reference_data_cc -bart transpose 3 4 reference_data_cc cc_reference_data - -bart fmac -C -s 8 $input_data cc_mat_P input_data_cc -bart transpose 3 4 input_data_cc cc_input_data - -bart ecalib -c0.7 -k7 -r$reference_lines_PE1 -m4 -S cc_reference_data maps -bart pics -l1 -r0.1 -i150 cc_input_data maps ims - -if "$debug";then - set +x -fi diff --git a/gadgets/bart/bart_helpers.cpp b/gadgets/bart/bart_helpers.cpp deleted file mode 100644 index 28fdb8cbf..000000000 --- a/gadgets/bart/bart_helpers.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "bart_helpers.h" - -#include -#include -#include - -#include - -// ============================================================================= - -namespace fs = Gadgetron::fs; - -fs::path internal::generate_unique_folder(const fs::path& working_directory) -{ - typedef std::chrono::system_clock clock_t; - - char buff[80]; - auto now = clock_t::to_time_t(clock_t::now()); - std::strftime(buff, sizeof(buff), "%H_%M_%S__", std::localtime(&now)); - std::random_device rd; - auto time_id(buff + std::to_string(std::uniform_int_distribution<>(1, 10000)(rd))); - // Get the current process ID - auto threadId = boost::lexical_cast(boost::this_thread::get_id()); - auto threadNumber(0UL); - sscanf(threadId.c_str(), "%lx", &threadNumber); - return working_directory / ("bart_" - + time_id - + "_" - + std::to_string(threadNumber)); -} - -// ======================================================================== - -void internal::ltrim(std::string &str) -{ - str.erase(str.begin(), std::find_if(str.begin(), str.end(), - [](int s) {return !std::isspace(s); })); -} - -void internal::rtrim(std::string &str) -{ - str.erase(std::find_if(str.rbegin(), str.rend(), - [](int s) {return !std::isspace(s);}).base(), - str.end()); -} - -void internal::trim(std::string &str) -{ - ltrim(str); - rtrim(str); -} - -std::string internal::get_output_filename(const std::string& command_line) -{ - boost::char_separator sep(" "); - std::vector tokens; - boost::tokenizer> tokenizer(command_line, sep); - for (auto& tok : tokenizer) { - tokens.push_back(tok); - } - - // Find begin of argument list - auto num_args(tokens.size()-1); - auto it(tokens.cbegin()); - if (*it == "bart") { - ++it; - --num_args; - } - // it now points to the name of the BART command - - if (*it == "bitmask" - || *it == "estdelay" - || *it == "estdims" - || *it == "estshift" - || *it == "estvar" - || *it == "nrmse" - || *it == "sdot" - || *it == "show" - || *it == "version") { - return ""; - } - else { - const auto end(tokens.cend()); - const auto arg1(*(it+1)); - const auto arg1_not_option(arg1[0] != '-'); - - /* - * Essentially, the algorithm considers only the BART functions where - * the output argument might not be the last one. - * - * For these commands, if a sufficient number of argument is provided - * there is no ambiguity possible since we can always find the last - * "flag-like" looking argument on the command line and then infer - * the position of the output from there. - * If there might be an ambiguity, we look at the first argument of - * the BART command and depending on whether it is a flag or not, - * we can infer the position of the output argument on the command - * line. - */ - if (*it == "ecalib") { - if (num_args > 3) { - auto it2 = --tokens.cend(); - for (; it2 != it && (*it2)[0] != '-'; --it2); - - const char& first((*it2)[0]); - const char& second((*it2)[1]); - if (first == '-' - && (it2->size() > 2 // handle cases like -t12 (ie. -t 12) - || second == 'S' - || second == 'W' - || second == 'I' - || second == '1' - || second == 'P' - || second == 'a')) { - GINFO("ecalib: flag\n"); - return *(it2 + 2); - } - else { - return *(it2 + 3); - } - } - else if (num_args == 3 && arg1_not_option) { - return *(end - 2); - } - - // Minimum arguments to ecalib - // 2 kspace sens - // 3 -I kspace sens - // 3 kspace sens ev-maps - // 4 -t 11 kspace sens - // 4 -P kspace sens ev-maps - // 4 -t11 kspace sens ev-maps - } - else if (*it == "ecaltwo") { - if (num_args > 6) { - auto it2 = --tokens.cend(); - for (; it2 != it && (*it2)[0] != '-'; --it2); - - const char& first((*it2)[0]); - const char& second((*it2)[1]); - if (first == '-' - && (it2->size() > 2 // handle cases like -t12 (ie. -t 12) - || second == 'S')) { - return *(it2 + 5); - } - else { - return *(it2 + 6); - } - } - else if (num_args == 6 && arg1[0] != '-') { - return *(end - 2); - } - // Minimum arguments to ecaltwo - // 6 x y z [] - // 6 -S x y z - // 7 -m 3 x y z - // 7 -S x y z [] - } - else if (*it == "nlinv") { - if (num_args > 3) { - auto it2 = --tokens.end(); - for (; it2 != it && (*it2)[0] != '-'; --it2); - - const char& first((*it2)[0]); - const char& second((*it2)[1]); - if (first == '-' - && (it2->size() > 2 // handle cases like -t12 (ie. -t 12) - || second == 'c' - || second == 'N' - || second == 'U' - || second == 'g' - || second == 'S')) { - return *(it2 + 2); - } - else { - return *(it2 + 3); - } - } - else if (num_args == 3 && arg1[0] != '-') { - return *(end - 2); - } - // Minimum arguments to nlinv - // 2 kspace output - // 3 kspace output sens - // 3 -S kspace output - // 4 -i d kspace output - // 4 -S kspace output sens - } - else if (*it == "whiten") { - if (num_args > 5) { - auto it2 = --tokens.end(); - for (; it2 != it && (*it2)[0] != '-'; --it2); - - const char& first((*it2)[0]); - const char& second((*it2)[1]); - if (first == '-' - && (it2->size() > 2 // handle cases like -t12 (ie. -t 12) - || second == 'n')) { - return *(it2 + 3); - } - else { - return *(it2 + 4); - } - } - else if(num_args == 5 && arg1_not_option) { - return *(end - 3); - } - else if (num_args == 4 && arg1_not_option) { - return *(end - 2); - } - // Minimum arguments to whiten - // 3 input ndata output - // 4 input ndata output optmat - // 4 -n input ndata output - // 5 -o asd input ndata output - // 5 -n input ndata output optmat - // 5 input ndata output optmat covar_out - } - } - return tokens.back(); -} diff --git a/gadgets/bart/bart_helpers.h b/gadgets/bart/bart_helpers.h deleted file mode 100644 index dc69d3428..000000000 --- a/gadgets/bart/bart_helpers.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef BART_HELPERS_H_INCLUDED -#define BART_HELPERS_H_INCLUDED - -#include "bartgadget.h" -#include "bart/bart_embed_api.h" - -namespace internal { - namespace fs = Gadgetron::fs; - - class ScopeGuard - { - public: - ScopeGuard(fs::path p) : p_(std::move(p)) - { - char buf[1024] = { '\0' }; - auto* ptr = getcwd(buf, 1024); - cwd_ = std::string(ptr); - auto r = chdir(p_.c_str()); - } - ~ScopeGuard() - { - if (is_active_) { - fs::remove_all(p_); - } - auto r = chdir(cwd_.c_str()); - deallocate_all_mem_cfl(); - } - - void dismiss() { is_active_ = false; } - private: - bool is_active_; - const fs::path p_; - fs::path cwd_; - }; - - fs::path generate_unique_folder(const fs::path& working_directory); - - void ltrim(std::string &str); - void rtrim(std::string &str); - void trim(std::string &str); - - std::string get_output_filename(const std::string& command_line); -} // namespace internal - -#endif //BART_HELPERS_H_INCLUDED diff --git a/gadgets/bart/bart_logger.cpp b/gadgets/bart/bart_logger.cpp deleted file mode 100644 index 26950ee34..000000000 --- a/gadgets/bart/bart_logger.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "log.h" - -#include "bart/bart_embed_api.h" - -enum debug_levels { DP_ERROR, DP_WARN, DP_INFO, DP_DEBUG1, DP_DEBUG2, DP_DEBUG3, DP_DEBUG4, DP_TRACE, DP_ALL }; - -extern "C" -void vendor_log(int level, - const char* /*func_name*/, - const char* file, - unsigned int line, - const char* message) -{ - const auto fname(file + std::string(" (BART)")); - const auto msg (message + std::string("\n")); - - if (-1 == debug_level) { - char* str = getenv("DEBUG_LEVEL"); - debug_level = (NULL != str) ? atoi(str) : DP_INFO; - } - - if (level <= debug_level) { - switch(level) { - case DP_ERROR: - Gadgetron::GadgetronLogger::instance()->log(Gadgetron::GADGETRON_LOG_LEVEL_ERROR, fname.c_str(), line, msg.c_str()); - break; - case DP_WARN: - Gadgetron::GadgetronLogger::instance()->log(Gadgetron::GADGETRON_LOG_LEVEL_WARNING, fname.c_str(), line, msg.c_str()); - break; - case DP_INFO: - Gadgetron::GadgetronLogger::instance()->log(Gadgetron::GADGETRON_LOG_LEVEL_INFO, fname.c_str(), line, msg.c_str()); - break; - default: - Gadgetron::GadgetronLogger::instance()->log(Gadgetron::GADGETRON_LOG_LEVEL_DEBUG, fname.c_str(), line, msg.c_str()); - } - } -} diff --git a/gadgets/bart/bartgadget.cpp b/gadgets/bart/bartgadget.cpp deleted file mode 100644 index bb7b5b153..000000000 --- a/gadgets/bart/bartgadget.cpp +++ /dev/null @@ -1,598 +0,0 @@ -/****************************************************************************** - * Description: Gadget using the Berkeley Advanced Reconstruction Toolbox (BART) - * Authors: - * Mahamadou Diakite, PhD. [1] - * Nguyen Damien, PhD. [2] - * Francesco Santini, PhD. [2] - * Institutions: - * [1] National Institutes of Health (NIH) - * [2] University of Basel, Switzerland - * Lang: C++ - * Date: 08/10/2018 - * Version: 1.5.0 - ******************************************************************************/ - -#include "bartgadget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "bart_helpers.h" - -enum bart_debug_levels { BART_DP_ERROR, BART_DP_WARN, BART_DP_INFO, BART_DP_DEBUG1, BART_DP_DEBUG2, BART_DP_DEBUG3, BART_DP_DEBUG4, BART_DP_TRACE, BART_DP_ALL }; - -// ============================================================================= - -std::vector Gadgetron::read_BART_hdr(fs::path &filename) -{ - return read_BART_hdr(filename); -} - -std::pair, std::vector>> -Gadgetron::read_BART_files(fs::path &filename) -{ - return read_BART_files(filename); -} - -// ============================================================================= - -namespace Gadgetron { - - BartGadget::BartGadget() : - dp{} - {} - - void BartGadget::replace_default_parameters(std::string & str) - { - std::string::size_type pos = 0u; - while ((pos = str.find('$', pos)) != std::string::npos) - { - auto pos_end = str.find(' ', pos); - auto pos_diff = pos_end - pos; - std::string tmp = str.substr(pos, pos_diff); - tmp.erase(0, 1); - if (tmp == std::string("recon_matrix_x")) - str.replace(pos, pos_diff, std::to_string(dp.recon_matrix_x)); - else if (tmp == std::string("recon_matrix_y")) - str.replace(pos, pos_diff, std::to_string(dp.recon_matrix_y)); - else if (tmp == std::string("recon_matrix_z")) - str.replace(pos, pos_diff, std::to_string(dp.recon_matrix_z)); - else if (tmp == std::string("FOV_x")) - str.replace(pos, pos_diff, std::to_string(dp.FOV_x)); - else if (tmp == std::string("FOV_y")) - str.replace(pos, pos_diff, std::to_string(dp.FOV_y)); - else if (tmp == std::string("FOV_z")) - str.replace(pos, pos_diff, std::to_string(dp.FOV_z)); - else if (tmp == std::string("acc_factor_PE1")) - str.replace(pos, pos_diff, std::to_string(dp.acc_factor_PE1)); - else if (tmp == std::string("acc_factor_PE2")) - str.replace(pos, pos_diff, std::to_string(dp.acc_factor_PE2)); - else if (tmp == std::string("reference_lines_PE1")) - str.replace(pos, pos_diff, std::to_string(dp.reference_lines_PE1)); - else if (tmp == std::string("reference_lines_PE2")) - str.replace(pos, pos_diff, std::to_string(dp.reference_lines_PE2)); - else if (tmp == std::string("input_data")) - str.replace(pos, pos_diff, dp.input_data); - else if (tmp == std::string("reference_data")) - str.replace(pos, pos_diff, dp.reference_data); - else if (tmp == std::string("traj_data")) - str.replace(pos, pos_diff, dp.traj_data); - else { - GERROR( "Unknown default parameter, please see the complete list of available parameters..."); - } - pos = pos_end; - } - } - - - int BartGadget::process_config(ACE_Message_Block * mb) - { - GADGET_CHECK_RETURN(BaseClass::process_config(mb) == GADGET_OK, GADGET_FAIL); - - /** Let's get some information about the incoming data **/ - ISMRMRD::IsmrmrdHeader h; - try { - deserialize(mb->rd_ptr(), h); - } - catch (...) { - GDEBUG("BartGadget::process_config: Failed to parse incoming ISMRMRD Header"); - } - - // =================================================================== - /* Data provided to the user might or might not be in-memory - * - * - if -DMEMONLY_CFL then we're always in-memory without extension - * - otherwise we add the *.mem extension if - * + if the memory behaviour is BART_ALL_IN_MEM - * + or if the memory behaviour is BART_MIX_DISK_MEM and the user requests it - */ - const auto append_mem_ext_in(!memonly_cfl - && (memory_behaviour_ == BART_ALL_IN_MEM - || (memory_behaviour_ == BART_MIX_DISK_MEM - && BartStoreGadgetronInputInMemory.value()))); - - dp.reference_data = std::string("reference_data") + (append_mem_ext_in ? ".mem" : ""); - dp.input_data = std::string("input_data") + (append_mem_ext_in ? ".mem" : ""); - dp.traj_data = std::string("traj_data") + (append_mem_ext_in ? ".mem" : ""); - - // =================================================================== - // Adjust BART's debug level - - GDEBUG_STREAM("BartGadget::process_config: setting BART debug level to " - << BartPrintfDebugLevel.value()); - - auto& bart_debug_level(debug_level); - if (BartPrintfDebugLevel.value() == "DP_ERROR") { - bart_debug_level = BART_DP_ERROR; - } - else if (BartPrintfDebugLevel.value() == "DP_WARN") { - bart_debug_level = BART_DP_WARN; - } - else if (BartPrintfDebugLevel.value() == "DP_INFO") { - bart_debug_level = BART_DP_INFO; - } - else if (BartPrintfDebugLevel.value() == "DP_DEBUG1") { - bart_debug_level = BART_DP_DEBUG1; - } - else if (BartPrintfDebugLevel.value() == "DP_DEBUG2") { - bart_debug_level = BART_DP_DEBUG2; - } - else if (BartPrintfDebugLevel.value() == "DP_DEBUG3") { - bart_debug_level = BART_DP_DEBUG3; - } - else if (BartPrintfDebugLevel.value() == "DP_DEBUG4") { - bart_debug_level = BART_DP_DEBUG4; - } - else if (BartPrintfDebugLevel.value() == "DP_TRACE") { - bart_debug_level = BART_DP_TRACE; - } - else if (BartPrintfDebugLevel.value() == "DP_ALL") { - bart_debug_level = BART_DP_ALL; - } - else { - GWARN("Unknown debug level! defaulting to BART_DP_INFO"); - bart_debug_level = BART_DP_INFO; - } - - // =================================================================== - // Check status of bart commands script - - if (AbsoluteBartCommandScript_path.value().empty()) - AbsoluteBartCommandScript_path.value(context.paths.gadgetron_home.string() + "/share/gadgetron/bart"); - - command_script_ = AbsoluteBartCommandScript_path.value(); - command_script_ /= BartCommandScript_name.value(); - - if (!fs::exists(command_script_)) { - GERROR("Can't find bart commands script: %s!\n", command_script_.c_str()); - return GADGET_FAIL; - } - - // =================================================================== - - memory_behaviour_ = BART_MIX_DISK_MEM; - if (BartFileBehaviour.value() == "BART_ALL_IN_MEM") { - memory_behaviour_ = BART_ALL_IN_MEM; - } - else if (BartFileBehaviour.value() == "BART_MIX_DISK_MEM") { - memory_behaviour_ = BART_MIX_DISK_MEM; - } - else { - GERROR_STREAM("Invalid value specified for BartFileBehaviour: " << BartFileBehaviour.value()); - return GADGET_FAIL; - } - - // =================================================================== - - for (const auto& enc: h.encoding) { - auto recon_space = enc.reconSpace; - - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Encoding matrix size: " << recon_space.matrixSize.x << " " << recon_space.matrixSize.y << " " << recon_space.matrixSize.z); - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Encoding field_of_view : " << recon_space.fieldOfView_mm.x << " " << recon_space.fieldOfView_mm.y << " " << recon_space.fieldOfView_mm.z); - dp.recon_matrix_x = recon_space.matrixSize.x; - dp.recon_matrix_y = recon_space.matrixSize.y; - dp.recon_matrix_z = recon_space.matrixSize.z; - dp.FOV_x = static_cast(recon_space.fieldOfView_mm.x); - dp.FOV_y = static_cast(recon_space.fieldOfView_mm.y); - dp.FOV_z = static_cast(recon_space.fieldOfView_mm.z); - - if (!enc.parallelImaging) - { - GDEBUG_STREAM("BartGadget::process_config: Parallel Imaging not enable..."); - } - else - { - auto p_imaging = *h.encoding.front().parallelImaging; - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: acceleration Factor along PE1 is " << p_imaging.accelerationFactor.kspace_encoding_step_1); - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: acceleration Factor along PE2 is " << p_imaging.accelerationFactor.kspace_encoding_step_2); - dp.acc_factor_PE1 = p_imaging.accelerationFactor.kspace_encoding_step_1; - dp.acc_factor_PE2 = p_imaging.accelerationFactor.kspace_encoding_step_2; - - if (p_imaging.accelerationFactor.kspace_encoding_step_2 > 1) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Limits of the size of the calibration region (PE1) " << h.userParameters->userParameterLong[0].name << " is " << h.userParameters->userParameterLong[0].value); - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Limits of the size of the calibration region (PE2) " << h.userParameters->userParameterLong[1].name << " is " << h.userParameters->userParameterLong[1].value); - dp.reference_lines_PE1 = h.userParameters->userParameterLong[0].value; - dp.reference_lines_PE2 = h.userParameters->userParameterLong[1].value; - } - else if (p_imaging.accelerationFactor.kspace_encoding_step_1 > 1) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Limits of the size of the calibration region (PE1) " << h.userParameters->userParameterLong[0].name << " is " << h.userParameters->userParameterLong[0].value); - dp.reference_lines_PE1 = h.userParameters->userParameterLong[0].value; - } - - auto calib = *p_imaging.calibrationMode; - auto separate = (calib == std::string("separate")); - auto embedded = (calib == std::string("embedded")); - auto external = (calib == std::string("external")); - auto interleaved = (calib == std::string("interleaved")); - auto other = (calib == std::string("other")); - - if (p_imaging.accelerationFactor.kspace_encoding_step_1 > 1 || p_imaging.accelerationFactor.kspace_encoding_step_2 > 1) - { - if (interleaved) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Calibration mode INTERLEAVE "); - } - else if (embedded) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Calibration mode EMBEDDED"); - } - else if (separate) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Calibration mode SEPARATE"); - } - else if (external) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Calibration mode EXTERNAL"); - } - else if (other) { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Calibration mode OTHER"); - } - else { - GDEBUG_CONDITION_STREAM(isVerboseON.value(), "BartGadget::process_config: Something went terribly wrong, this should never happen!"); - return GADGET_FAIL; - } - } - - } - - } - return GADGET_OK; - } - - int BartGadget::process(GadgetContainerMessage* m1) - { - static std::mutex mtx; - std::lock_guard guard(mtx); - - constexpr auto memonly_cfl = -#ifdef MEMONLY_CFL - true -#else - false -#endif /* MEMONLY_CFL */ - ; - - GINFO_STREAM("Process start"); - - - auto generated_files_folder(internal::generate_unique_folder(BartWorkingDirectory_path.value())); - - bool create_folder(!memonly_cfl - || memory_behaviour_ != BART_ALL_IN_MEM); - if (create_folder) { - if (!(fs::exists(generated_files_folder) - && fs::is_directory(generated_files_folder))) { - if (fs::create_directories(generated_files_folder)){ - GDEBUG_STREAM("Folder to store *.hdr & *.cfl files is " << generated_files_folder); - } - else { - GERROR("Folder to store *.hdr & *.cfl files doesn't exist...\n"); - return GADGET_FAIL; - } - } - } - - internal::ScopeGuard cleanup_guard(generated_files_folder); - if (!create_folder) { - cleanup_guard.dismiss(); - } - - // Gadgetron data is always in-memory - const auto ref_filename_src = std::string("meas_gadgetron_ref") + (!memonly_cfl ? ".mem" : ""); - const auto data_filename_src = std::string("meas_gadgetron_input") + (!memonly_cfl ? ".mem" : ""); - const auto traj_filename_src = std::string("meas_gadgetron_traj") + (!memonly_cfl ? ".mem" : ""); - - - /*** PROCESS EACH DATASET ***/ - - auto it(0UL); - for(auto& recon_bit: m1->getObjectPtr()->rbit_) { - - bool has_traj(recon_bit.data_.trajectory_); - - // Grab a reference to the buffer containing the reference data - auto& input_ref = (*recon_bit.ref_).data_; - // Data 7D, fixed order [E0, E1, E2, CHA, N, S, LOC] - std::vector DIMS_ref{static_cast(input_ref.get_size(0)), - static_cast(input_ref.get_size(1)), - static_cast(input_ref.get_size(2)), - static_cast(input_ref.get_size(3)), - static_cast(input_ref.get_size(4)), - static_cast(input_ref.get_size(5)), - static_cast(input_ref.get_size(6))}; - - // Grab a reference to the buffer containing the image data - auto& input = recon_bit.data_.data_; - // Data 7D, fixed order [E0, E1, E2, CHA, N, S, LOC] - std::vector DIMS{static_cast(input.get_size(0)), - static_cast(input.get_size(1)), - static_cast(input.get_size(2)), - static_cast(input.get_size(3)), - static_cast(input.get_size(4)), - static_cast(input.get_size(5)), - static_cast(input.get_size(6))}; - - // Grab a reference to the buffer containing the image trajectory data (if present) - std::unique_ptr>> traj(nullptr); - if (has_traj) { - auto& traj_real = *recon_bit.data_.trajectory_; - traj = std::make_unique>>(traj_real.get_dimensions()); - // Data 7D, fixed order [E0, E1, E2, CHA, N, S, LOC] - std::vector DIMS_traj{static_cast(traj_real.get_size(0)), - static_cast(traj_real.get_size(1)), - static_cast(traj_real.get_size(2)), - static_cast(traj_real.get_size(3)), - static_cast(traj_real.get_size(4)), - static_cast(traj_real.get_size(5)), - static_cast(traj_real.get_size(6))}; - std::transform(traj_real.begin(), traj_real.end(), - traj->begin(), - [] (float r) { return std::complex(r, 0.); }); - - register_mem_cfl_non_managed(traj_filename_src.c_str(), DIMS_traj.size(), &DIMS_traj[0], &(*traj)[0]); - } - - /* The reference data will be pointing to the image data if there is - no reference scan. Therefore, we won't write the reference data - into files if it's pointing to the raw data.*/ - if (DIMS_ref != DIMS) - { - register_mem_cfl_non_managed(ref_filename_src.c_str(), DIMS_ref.size(), &DIMS_ref[0], &input_ref[0]); - } - - register_mem_cfl_non_managed(data_filename_src.c_str(), DIMS.size(), &DIMS[0], &input[0]); - - - if (DIMS_ref != DIMS) - { - std::ostringstream cmd; - cmd << "bart resize -c 0 " << DIMS[0] << " 1 " << DIMS[1] << " 2 " << DIMS[2] - << " " << ref_filename_src << " " << dp.reference_data; - - GDEBUG_STREAM("Gadgetron data is loaded to " << ref_filename_src); - GDEBUG_STREAM("BART filename for reference data is " << dp.reference_data); - - if (!call_BART(cmd.str())) - { - return GADGET_FAIL; - } - } - - std::ostringstream cmd2; - if (DIMS[4] != 1) - cmd2 << "bart reshape 1023 " << DIMS[0] << " " << DIMS[1] << " " << DIMS[2] << " " << DIMS[3] << " 1 1 1 " << DIMS[5] << " " << DIMS[6] << " " << DIMS[4]; - else - cmd2 << "bart copy"; - - cmd2 << " " << data_filename_src << " " << dp.input_data; - - GDEBUG_STREAM("Gadgetron data is loaded to " << data_filename_src); - GDEBUG_STREAM("BART filename for data is " << dp.input_data); - - if (!call_BART(cmd2.str())) - { - return GADGET_FAIL; - } - - if (has_traj) { - std::ostringstream cmd3; - if (DIMS[4] != 1) - cmd3 << "bart reshape 1023 " << DIMS[0] << " " << DIMS[1] << " " << DIMS[2] << " " << DIMS[3] << " 1 1 1 " << DIMS[5] << " " << DIMS[6] << " " << DIMS[4]; - else - cmd3 << "bart copy"; - - cmd3 << " " << traj_filename_src << " " << dp.traj_data; - - GDEBUG_STREAM("Gadgetron trajectory is loaded to " << traj_filename_src); - GDEBUG_STREAM("BART filename for trajectory is " << dp.traj_data); - - if (!call_BART(cmd3.str())) - { - return GADGET_FAIL; - } - } - - /*** CALL BART COMMAND LINE from the scripting file ***/ - GDEBUG("Starting processing user script\n"); - - std::string Commands_Line; - std::ifstream inputFile(command_script_.string()); - if (inputFile.is_open()) - { - std::string Line; - while (getline(inputFile, Line)) - { - // crop comment - Line = Line.substr(0, Line.find_first_of('#')); - - internal::trim(Line); - if (Line.empty() || Line.compare(0, 4, "bart") != 0) - continue; - - replace_default_parameters(Line); - if (!call_BART(Line)) - { - return GADGET_FAIL; - } - - Commands_Line = Line; - } - } - else - { - GERROR("Unable to open %s\n", command_script_.c_str()); - return GADGET_FAIL; - } - - // ============================================================== - - fs::path outputFile(internal::get_output_filename(Commands_Line)); - GDEBUG_STREAM("Detected last output file: " << outputFile); - - // Reshaped data is always in-memory - fs::path outputFileReshape(outputFile); - - // Remove the extension from the user's output if needed - if (outputFileReshape.extension() == ".mem") { - outputFileReshape.replace_extension(); - } - outputFileReshape += std::string("_reshape") + (!memonly_cfl ? ".mem" : ""); - - // Reformat the data back to Gadgetron format - std::vector header(16); - if (memonly_cfl || outputFile.extension() == ".mem") { - load_mem_cfl(outputFile.c_str(), header.size(), header.data()); - } - else { - auto tmp(generated_files_folder / outputFile); - header = read_BART_hdr(tmp); - } - - std::ostringstream cmd4; - cmd4 << "bart reshape 1023 " << header[0] << " " << header[1] << " " << header[2] << " " << header[3] << " " << header[9] * header[4] << - " " << header[5] << " " << header[6] << " " << header[7] << " " << header[8] << " 1 " << outputFile.c_str() << " " << outputFileReshape.c_str(); - - if (!call_BART(cmd4.str())) - { - return GADGET_FAIL; - } - - /**** READ FROM BART FILES ***/ - std::vector DIMS_OUT(16); - auto data = reinterpret_cast*>(load_mem_cfl(outputFileReshape.c_str(), DIMS_OUT.size(), DIMS_OUT.data())); - - if (data == nullptr) { - GERROR("Failed to retrieve data from in-memory CFL file!"); - return GADGET_FAIL; - } - - - if (isBartFileBeingStored.value()) { - cleanup_guard.dismiss(); - } - - IsmrmrdImageArray imarray; - - // Grab data from BART files - std::vector BART_DATA_dims{ - static_cast(std::accumulate(DIMS_OUT.begin(), DIMS_OUT.end(), 1, std::multiplies()))}; - hoNDArray> DATA(BART_DATA_dims, data); - - // The image array data will be [E0,E1,E2,1,N,S,LOC] - std::vector data_dims(DIMS_OUT.begin(), DIMS_OUT.begin()+7); - DATA.reshape(data_dims); - - // Extract the first image from each time frame (depending on the number of maps generated by the user) - std::vector data_dims_Final{static_cast(DIMS_OUT[0]), - static_cast(DIMS_OUT[1]), - static_cast(DIMS_OUT[2]), - static_cast(DIMS_OUT[3]), - static_cast(DIMS_OUT[4] / header[4]), - static_cast(DIMS_OUT[5]), - static_cast(DIMS_OUT[6])}; - assert(header[4] > 0); - imarray.data_.create(data_dims_Final); - - std::vector > DATA_Final; - DATA_Final.reserve(std::accumulate(data_dims_Final.begin(), data_dims_Final.end(), 1, std::multiplies())); - - //Each chunk will be [E0,E1,E2,CHA] big - std::vector chunk_dims{data_dims_Final[0], data_dims_Final[1], data_dims_Final[2], data_dims_Final[3]}; - const std::vector Temp_one_1d(1, chunk_dims[0] * chunk_dims[1] * chunk_dims[2] * chunk_dims[3]); - - for (uint16_t loc = 0; loc < data_dims[6]; ++loc) { - for (uint16_t s = 0; s < data_dims[5]; ++s) { - for (uint16_t n = 0; n < data_dims[4]; n += header[4]) { - //Grab a wrapper around the relevant chunk of data [E0,E1,E2,CHA] for this loc, n, and s - auto chunk = hoNDArray >(chunk_dims, &DATA(0, 0, 0, 0, n, s, loc)); - chunk.reshape(Temp_one_1d); - DATA_Final.insert(DATA_Final.end(), chunk.begin(), chunk.end()); - } - } - } - - std::copy(DATA_Final.begin(), DATA_Final.end(), imarray.data_.begin()); - - compute_image_header(recon_bit, imarray, it); - send_out_image_array(imarray, it, image_series.value() + (static_cast(it) + 1), GADGETRON_IMAGE_REGULAR); - ++it; - } - - m1->release(); - return GADGET_OK; - } - - bool call_BART(const std::string &cmdline) - { - GINFO_STREAM("Executing BART command: " << cmdline); - enum { MAX_ARGS = 256 }; - - int argc(0); - char* argv[MAX_ARGS]; - - auto cmdline_s = std::make_unique(cmdline.size()+1); - strcpy(cmdline_s.get(), cmdline.c_str()); - - char *p2 = strtok(cmdline_s.get(), " "); - while (p2 && argc < MAX_ARGS-1) - { - argv[argc++] = p2; - p2 = strtok(nullptr, " "); - } - argv[argc] = nullptr; - - // boost::char_separator sep(" "); - // boost::tokenizer> tokens(cmdline.begin(), - // cmdline.end(), - // sep); - // std::vector> tmp; - // auto k(0UL); - // for (auto tok: tokens) { - // tmp.push_back(std::make_unique(tok.size()+1)); - // strcpy(tmp.back().get(), tok.c_str()); - // argv[k++] = tmp.back().get(); - // } - // argc = tmp.size(); - - char out_str[512] = {'\0'}; - auto ret(bart_command(512, out_str, argc, argv)); - if (ret == 0) { - if (strlen(out_str) > 0) { - GINFO(out_str); - } - return true; - } - // else { - GERROR_STREAM("BART command failed with return code: " << ret); - return false; - // } - } - - GADGET_FACTORY_DECLARE(BartGadget) -} diff --git a/gadgets/bart/bartgadget.h b/gadgets/bart/bartgadget.h deleted file mode 100644 index 70a6a3a12..000000000 --- a/gadgets/bart/bartgadget.h +++ /dev/null @@ -1,202 +0,0 @@ -/****************************************************************************** - * Description: Gadget using the Berkeley Advanced Reconstruction Toolbox (BART) - * Authors: - * Mahamadou Diakite, PhD. [1] - * Nguyen Damien, PhD. [2] - * Francesco Santini, PhD. [2] - * Institutions: - * [1] National Institutes of Health (NIH) - * [2] University of Basel, Switzerland - * Lang: C++ - * Date: 08/10/2018 - * Version: 1.5.0 - ******************************************************************************/ - -#ifndef BART_GADGET_H -#define BART_GADGET_H - -#include "generic_recon_gadgets/GenericReconGadget.h" - -#include -#include -#include -#include -#include -#include - -#include - - -namespace Gadgetron { - namespace fs = boost::filesystem; - - // The user is free to add more parameters as the need arises. - struct Default_parameters - { - uint16_t recon_matrix_x; - uint16_t recon_matrix_y; - uint16_t recon_matrix_z; - uint16_t FOV_x; - uint16_t FOV_y; - uint16_t FOV_z; - uint16_t acc_factor_PE1; - uint16_t acc_factor_PE2; - uint16_t reference_lines_PE1; - uint16_t reference_lines_PE2; - std::string reference_data; - std::string input_data; - std::string traj_data; - }; - - class BartGadget final : public GenericReconGadget - { - public: - enum bart_memory_behaviour {BART_ALL_IN_MEM, BART_ALL_ON_DISK, BART_MIX_DISK_MEM}; - - using BaseClass = GenericReconGadget; - - BartGadget(); - ~BartGadget() = default; - - protected: - GADGET_PROPERTY(isVerboseON, bool, "Display some information about the incoming data", false); - // This property has no effect if BartGadget is compiled with -DMEMONLY_CFL or if the memory behaviour is either BART_ALL_IN_MEM or BART_ALL_ON_DISK - GADGET_PROPERTY(BartStoreGadgetronInputInMemory, bool, "Whether BartGadget should always store incoming data in-memory (might append *.mem extension)", true); - // The property controls how BART stores CFL files. Possible values are: BART_ALL_IN_MEM, BART_MIX_MEM_DISK, BART_ALL_ON_DISK - GADGET_PROPERTY(BartFileBehaviour, std::string, "Controls how BART stores files: either all in memory, or mixed disk/memory behaviour", "BART_MIX_DISK_MEM"); - GADGET_PROPERTY(BartWorkingDirectory_path, std::string, "Absolute path to a temporary file location for generated BART files", "/tmp/gadgetron/"); - GADGET_PROPERTY(AbsoluteBartCommandScript_path, std::string, "Absolute path to BART script(s)", ""); - GADGET_PROPERTY(BartCommandScript_name, std::string, "Script file containing BART command(s) to be loaded", ""); - GADGET_PROPERTY(isBartFileBeingStored, bool, "Keep generated BART files on the disk after the processing ends (has no effect if BART_ALL_IN_MEM is specified as behaviour)", false); - GADGET_PROPERTY(image_series, int, "Set image series", 0); - GADGET_PROPERTY(BartPrintfDebugLevel, std::string, "Debug level for BART outputs (DP_ERROR, DP_WARN, DP_INFO, DP_DEBUG1,etc.)", "DP_INFO"); - - int process_config(ACE_Message_Block* mb); - int process(GadgetContainerMessage* m1); - - private: - - static constexpr auto memonly_cfl = -#ifdef MEMONLY_CFL - true -#else - false -#endif /* MEMONLY_CFL */ - ; - - Default_parameters dp; - bart_memory_behaviour memory_behaviour_; - fs::path command_script_; - - void replace_default_parameters(std::string &str); - - }; - - bool call_BART(const std::string &cmdline); - - // Read BART files - template - std::vector read_BART_hdr(fs::path &filename) - { - std::vector DIMS; - - std::ifstream infile((filename += ".hdr").c_str()); - if (infile) - { - std::vector tokens; - std::string line; - - while (std::getline(infile, line, '\n')) - { - tokens.push_back(line); - } - - // Parse the dimensions - std::stringstream ss(tokens[1]); - std::string items; - while (getline(ss, items, ' ')) { - DIMS.push_back(std::stoi(items)); - } - } - else - { - GERROR("Failed to open file: %s\n", filename.c_str()); - } - - return DIMS; - } - - template - std::pair, std::vector>> - read_BART_files(fs::path &filename) - { - // Load the header file - auto DIMS = read_BART_hdr(filename); - - // Load the cfl file - std::ifstream infile((filename += ".cfl").c_str(), std::ifstream::binary); - if (!infile) - { - GERROR("Failed to open file: %s\n", filename.c_str()); - return std::make_pair(DIMS, std::vector>()); - } - else - { - // First determine data size - infile.seekg(0, infile.end); - size_t size(infile.tellg()); - - // Now read data from file - infile.seekg(0); - std::vector> Data(size/sizeof(float)/2.); - infile.read(reinterpret_cast(Data.data()), size); - - return std::make_pair(DIMS, Data); - } - } - - // For convenience - std::vector read_BART_hdr(boost::filesystem::path &filename); - std::pair< std::vector, std::vector > > read_BART_files(fs::path &filename); - - // ------------------------------------------------------------------------ - // Write BART files - template - void write_BART_hdr(fs::path filename, const std::vector& DIMS) - { - constexpr size_t MAX_DIMS = 16; - std::vector v(MAX_DIMS, 1); - assert(DIMS.size() < MAX_DIMS); - std::copy(DIMS.cbegin(), DIMS.cend(), v.begin()); - std::ofstream pFile((filename += ".hdr").c_str()); - if (!pFile) - GERROR("Failed to write into file: %s\n", filename); - pFile << "# Dimensions\n"; - std::copy(v.cbegin(), v.cend(), std::ostream_iterator(pFile, " ")); - } - - template - void write_BART_Files(fs::path filename, const std::vector& DIMS, const std::vector>& DATA) - { - GDEBUG("Writing CFL file to %s\n", filename.c_str()); - write_BART_hdr(filename, DIMS); - std::ofstream pFile((filename += ".cfl").c_str(), - std::ofstream::out | std::ofstream::binary); - if (!pFile) - GERROR("Failed to write into file: %s\n", filename); - pFile.write(reinterpret_cast(&DATA[0]), DATA.size() * sizeof(std::complex)); - } - - template - void write_BART_Files(fs::path filename, const std::vector&DIMS, const hoNDArray>& DATA) - { - GDEBUG("Writing CFL file to %s\n", filename.c_str()); - write_BART_hdr(filename, DIMS); - std::ofstream pFile((filename += ".cfl").c_str(), - std::ofstream::out | std::ofstream::binary); - if (!pFile) - GERROR("Failed to write into file: %s\n", filename); - pFile.write(reinterpret_cast(&DATA[0]), DATA.get_number_of_bytes()); - } -} // namespace Gadgetron -#endif //BART_GADGET_H diff --git a/gadgets/cartesian/CMakeLists.txt b/gadgets/cartesian/CMakeLists.txt deleted file mode 100644 index 452d41fee..000000000 --- a/gadgets/cartesian/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -add_library(pingvin_cartesian SHARED - CartesianToGenericGadget.h - CartesianToGenericGadget.cpp -) - -set_target_properties(pingvin_cartesian PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_cartesian pingvin_toolbox_cpucore - pingvin_core - pingvin_toolbox_log - pingvin_mricore - pingvin_toolbox_cpucore_math - ) - - -install (FILES CartesianToGenericGadget.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - -install(TARGETS pingvin_cartesian - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) \ No newline at end of file diff --git a/gadgets/cartesian/CartesianToGenericGadget.cpp b/gadgets/cartesian/CartesianToGenericGadget.cpp deleted file mode 100644 index f671539d5..000000000 --- a/gadgets/cartesian/CartesianToGenericGadget.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include "CartesianToGenericGadget.h" -#include "ismrmrd/xml.h" - -namespace Gadgetron{ - - CartesianToGenericGadget::CartesianToGenericGadget() - { - } - - CartesianToGenericGadget::~CartesianToGenericGadget() {} - - int CartesianToGenericGadget::process_config(ACE_Message_Block* mb) - { - // Get the Ismrmrd header - // - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - - if (h.encoding.size() != 1) { - GDEBUG("This Gadget only supports one encoding space\n"); - return GADGET_FAIL; - } - - // Get the encoding space and trajectory description - ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; - - // Enforcement of the matrix size being a multiple of the "warp size" - warp_size_ = matrix_size_as_multiple_of.value(); - - matrix_size_.push_back( (e_space.matrixSize.x+warp_size_-1)/warp_size_*warp_size_); - matrix_size_.push_back( (e_space.matrixSize.y+warp_size_-1)/warp_size_*warp_size_); - - center_phase_ = e_limits.kspace_encoding_step_1 ? e_limits.kspace_encoding_step_1->center : 0; - - return GADGET_OK; - } - - int CartesianToGenericGadget:: - process(GadgetContainerMessage *m1, - GadgetContainerMessage< hoNDArray< std::complex > > *m2) - { - // Noise should have been consumed by the noise adjust, but just in case... - // - - bool is_noise = m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT); - if (is_noise) { - m1->release(); - return GADGET_OK; - } - - // Make a new array as continuation of m1, and pass along - // - - size_t samples_per_readout = m1->getObjectPtr()->number_of_samples; - size_t center_sample = m1->getObjectPtr()->center_sample; - size_t offset_readout = (matrix_size_[0]>>1)-center_sample; // In case of partial Fourier - size_t offset_phase = (matrix_size_[1]>>1)-center_phase_; // In case of partial Fourier - size_t phase_encode_step = m1->getObjectPtr()->idx.kspace_encode_step_1; - - std::vector trajectory_dimensions; - trajectory_dimensions.push_back(3); - trajectory_dimensions.push_back(samples_per_readout); - - GadgetContainerMessage< hoNDArray > *cont = new GadgetContainerMessage< hoNDArray >(); - cont->getObjectPtr()->create(trajectory_dimensions); - m2->cont(cont); - - float *traj_ptr = cont->getObjectPtr()->get_data_ptr(); - - for( size_t sample=0; samplenext()->putq(m1) < 0) { - GDEBUG("Failed to put job on queue.\n"); - return GADGET_FAIL; - } - - return GADGET_OK; - } - - GADGET_FACTORY_DECLARE(CartesianToGenericGadget) -} diff --git a/gadgets/cartesian/CartesianToGenericGadget.h b/gadgets/cartesian/CartesianToGenericGadget.h deleted file mode 100644 index b098dccd1..000000000 --- a/gadgets/cartesian/CartesianToGenericGadget.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef CartesianToGenericGadget_H -#define CartesianToGenericGadget_H -#pragma once - -#include "Gadget.h" -#include "hoNDArray.h" - -#include -#include -#include -#include - -namespace Gadgetron{ - - class CartesianToGenericGadget : - public Gadget2< ISMRMRD::AcquisitionHeader, hoNDArray< std::complex > > - { - - public: - CartesianToGenericGadget(); - virtual ~CartesianToGenericGadget(); - - protected: - GADGET_PROPERTY(matrix_size_as_multiple_of, int, "Force the matrix size to be a multiple of", 1); - - virtual int process_config(ACE_Message_Block* mb); - virtual int process(GadgetContainerMessage< ISMRMRD::AcquisitionHeader >* m1, - GadgetContainerMessage< hoNDArray< std::complex > > * m2); - - private: - std::vector matrix_size_; - unsigned short center_phase_; - - // We can enforce the encoding space dimension - // to be a multiple of the "warp size" (required for the gpu nfft) - unsigned int warp_size_; - }; -} -#endif //CartesianToGenericGadget_H diff --git a/gadgets/cmr/CMakeLists.txt b/gadgets/cmr/CMakeLists.txt index 9b4eb04f9..1445d6b95 100644 --- a/gadgets/cmr/CMakeLists.txt +++ b/gadgets/cmr/CMakeLists.txt @@ -23,9 +23,7 @@ set( pingvin_cmr_src_files set( config_BinningCine_files config/BinningCine/CMR_2DT_RTCine_KspaceBinning.xml - config/BinningCine/CMR_2DT_RTCine_KspaceBinning_Cloud.xml - config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries.xml - config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries_Cloud.xml ) + config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries.xml) source_group(config/BinningCine FILES ${config_BinningCine_files}) diff --git a/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_Cloud.xml b/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_Cloud.xml deleted file mode 100644 index e7170ac0d..000000000 --- a/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_Cloud.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - 2 - - - - - - - NoiseAdjust - pingvin_mricore - NoiseAdjustGadget - - - - - AsymmetricEcho - pingvin_mricore - AsymmetricEchoAdjustROGadget - - - - - RemoveROOversampling - pingvin_mricore - RemoveROOversamplingGadget - - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - - - - - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - - - - - - - - - - - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - - - - - - - - - - - - - - - - - BufferReader - pingvin_core_readers - - - IsmrmrdImageArrayReader - pingvin_core_readers - - - - - BufferWriter - pingvin_core_writers - - - IsmrmrdImageArrayWriter - pingvin_core_writers - - - - - - - Recon - pingvin_cmr - CmrCartesianKSpaceBinningCineGadget - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - - - - - - - - - - - - - - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - - - - - - - - - - - - - - - - - - - - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - - - - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - - - - - - - - - - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - - - - - - diff --git a/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries_Cloud.xml b/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries_Cloud.xml deleted file mode 100644 index 122116997..000000000 --- a/gadgets/cmr/config/BinningCine/CMR_2DT_RTCine_KspaceBinning_MultiSeries_Cloud.xml +++ /dev/null @@ -1,257 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Strue - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingfalse - verbosefalse - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres-1 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_cmr - CmrCartesianKSpaceBinningCineGadget - - number_of_output_phases30 - send_out_rawfalse - send_out_multiple_series_by_slicetrue - - use_multiple_channel_recontrue - use_nonlinear_binning_recontrue - - time_tick2.5 - arrhythmia_rejector_factor0.25 - - - grappa_kSize_RO5 - grappa_kSize_E14 - grappa_reg_lamda0.0005 - downstream_coil_compression_num_modesKept0 - downstream_coil_compression_thres0.025 - - - kspace_binning_interpolate_heart_beat_imagestrue - kspace_binning_navigator_acceptance_window0.65 - kspace_binning_max_temporal_window2.0 - kspace_binning_minimal_cardiac_phase_width25.0 - - kspace_binning_moco_reg_strength12.0 - kspace_binning_moco_iters32 64 100 100 100 - - kspace_binning_kSize_RO7 - kspace_binning_kSize_E17 - kspace_binning_reg_lamda0.005 - kspace_binning_linear_iter_max90 - kspace_binning_linear_iter_thres0.0015 - - kspace_binning_nonlinear_iter_max25 - kspace_binning_nonlinear_iter_thres0.004 - kspace_binning_nonlinear_data_fidelity_lamda1.0 - kspace_binning_nonlinear_image_reg_lamda0.00015 - kspace_binning_nonlinear_reg_N_weighting_ratio10.0 - kspace_binning_nonlinear_reg_use_coil_sen_mapfalse - kspace_binning_nonlinear_reg_with_approx_coefftrue - kspace_binning_nonlinear_reg_wav_namedb2 - - - debug_folder - perform_timingtrue - verbosetrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/dicom/CMakeLists.txt b/gadgets/dicom/CMakeLists.txt deleted file mode 100644 index c0a91f0ea..000000000 --- a/gadgets/dicom/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# DCMTK-necessary preprocessor flags -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_CONFIG_H -D_REENTRANT -D_OSF_SOURCE") - -set(Boost_NO_BOOST_CMAKE ON) -find_package(Boost COMPONENTS date_time REQUIRED) - -set(GT_DICOM_LIBRARIES - dcmdata - oflog - ofstd - z m pthread) -if (APPLE) - list(APPEND GT_DICOM_LIBRARIES iconv) -endif () - -# sanity check: -message("DCMTK ${DCMTK_HOME}") -message("Include: ${DCMTK_INCLUDE_DIRS}") -message("Libraries: ${GT_DICOM_LIBRARIES}") - -set(pingvin_dicom_header_files - DicomFinishGadget.h - DicomImageWriter.h - dicom_ismrmrd_utility.h ) - -set(pingvin_dicom_src_files - DicomFinishGadget.cpp - DicomImageWriter.cpp - dicom_ismrmrd_utility.cpp ) - -set(pingvin_dicom_config_files dicom.xml ) - -add_library(pingvin_dicom SHARED - ${pingvin_dicom_header_files} - ${pingvin_dicom_src_files} - ${pingvin_dicom_config_files} ) - -set_target_properties(pingvin_dicom PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_include_directories(pingvin_dicom ${DCMTK_INCLUDE_DIRS}) - -target_link_libraries(pingvin_dicom - pingvin_core - pingvin_mricore - pingvin_toolbox_log - pingvin_toolbox_cpucore - ${GT_DICOM_LIBRARIES} ) - -if(ARMADILLO_FOUND) - target_link_libraries(pingvin_dicom pingvin_toolbox_cpucore_math ) -endif() - -install( - FILES ${pingvin_dicom_header_files} - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - -install(TARGETS pingvin_dicom - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install(FILES ${pingvin_dicom_config_files} DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/dicom/DicomFinishGadget.cpp b/gadgets/dicom/DicomFinishGadget.cpp deleted file mode 100644 index bbfa35bd3..000000000 --- a/gadgets/dicom/DicomFinishGadget.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include "boost/date_time/gregorian/gregorian.hpp" - -#include "DicomFinishGadget.h" -#include "ismrmrd/xml.h" - -namespace Gadgetron { - - int DicomFinishGadget::process_config(ACE_Message_Block* mb) - { - ISMRMRD::IsmrmrdHeader h; - deserialize(mb->rd_ptr(), h); - - xml = h; - - Gadgetron::fill_dicom_image_from_ismrmrd_header(h, dcmFile); - - ISMRMRD::MeasurementInformation meas_info = *h.measurementInformation; - - if (meas_info.seriesInstanceUIDRoot) { - seriesIUIDRoot = *meas_info.seriesInstanceUIDRoot; - } - - if (meas_info.initialSeriesNumber) { - this->initialSeriesNumber = (long)*meas_info.initialSeriesNumber; - } - else { - this->initialSeriesNumber = 0; - } - - return GADGET_OK; - } - - int DicomFinishGadget::process(GadgetContainerMessage* m1) - { - - - // -------------------------------------------------- - ISMRMRD::ImageHeader *img = m1->getObjectPtr(); - - uint16_t data_type = img->data_type; - - if (data_type == ISMRMRD::ISMRMRD_USHORT) - { - GadgetContainerMessage< hoNDArray< unsigned short > >* datamb = AsContainerMessage< hoNDArray< unsigned short > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for unsigned short ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_SHORT) - { - GadgetContainerMessage< hoNDArray< short > >* datamb = AsContainerMessage< hoNDArray< short > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for short ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_UINT) - { - GadgetContainerMessage< hoNDArray< unsigned int > >* datamb = AsContainerMessage< hoNDArray< unsigned int > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for unsigned int ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_INT) - { - GadgetContainerMessage< hoNDArray< int > >* datamb = AsContainerMessage< hoNDArray< int > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for int ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_FLOAT) - { - GadgetContainerMessage< hoNDArray< float > >* datamb = AsContainerMessage< hoNDArray< float > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for float ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_DOUBLE) - { - GadgetContainerMessage< hoNDArray< double > >* datamb = AsContainerMessage< hoNDArray< double > >(m1->cont()); - if (!datamb) - { - GERROR("DicomFinishGadget::process, invalid image message objects\n"); - return GADGET_FAIL; - } - - if (this->write_data_attrib(m1, datamb) != GADGET_OK) - { - GERROR("DicomFinishGadget::write_data_attrib failed for double ... \n"); - return GADGET_FAIL; - } - } - else if (data_type == ISMRMRD::ISMRMRD_CXFLOAT) - { - GERROR("DicomFinishGadget::process, does not support ISMRMRD_CXFLOAT data type\n"); - return GADGET_FAIL; - } - else if (data_type == ISMRMRD::ISMRMRD_CXDOUBLE) - { - GERROR("DicomFinishGadget::process, does not support ISMRMRD_CXDOUBLE data type\n"); - return GADGET_FAIL; - } - - return GADGET_OK; - } - - GADGET_FACTORY_DECLARE(DicomFinishGadget) - -} /* namespace Gadgetron */ diff --git a/gadgets/dicom/DicomFinishGadget.h b/gadgets/dicom/DicomFinishGadget.h deleted file mode 100644 index c6c437087..000000000 --- a/gadgets/dicom/DicomFinishGadget.h +++ /dev/null @@ -1,184 +0,0 @@ -/** \file DicomFinishGadget.h -\brief Assemble the dicom images and send out - -The dicom image is sent out with message id -> dicom image -> dicom image name -> meta attributes -\author Hui Xue -*/ - -#ifndef DICOMFINISHGADGET_H -#define DICOMFINISHGADGET_H - - -#include "Gadget.h" -#include "hoNDArray.h" -#include "ismrmrd/meta.h" -#include "ismrmrd/ismrmrd.h" - -#include "dcmtk/config/osconfig.h" -#include "dcmtk/ofstd/ofstdinc.h" -#define INCLUDE_CSTDLIB -#define INCLUDE_CSTDIO -#define INCLUDE_CSTRING -#include "dcmtk/dcmdata/dctk.h" -#include "dcmtk/dcmdata/dcostrmb.h" - -#include "mri_core_def.h" - -#include "dicom_ismrmrd_utility.h" - -#include -#include -#include - -namespace Gadgetron -{ - class DicomFinishGadget : public Gadget1< ISMRMRD::ImageHeader > - { - public: - - typedef Gadget1 BaseClass; - - DicomFinishGadget() - : BaseClass() - , dcmFile() - , initialSeriesNumber(0) - , seriesIUIDRoot() - { } - - protected: - - virtual int process_config(ACE_Message_Block * mb); - virtual int process(GadgetContainerMessage* m1); - - template - int write_data_attrib(GadgetContainerMessage* m1, GadgetContainerMessage< hoNDArray< T > >* m2) - { - - GadgetContainerMessage< ISMRMRD::MetaContainer >* m3 = AsContainerMessage< ISMRMRD::MetaContainer >(m2->cont()); - - std::string filename; - - if (m3) - { - ISMRMRD::MetaContainer* img_attrib = m3->getObjectPtr(); - - size_t n; - - size_t num = img_attrib->length(GADGETRON_DATA_ROLE); - - std::vector dataRole; - if (num == 0) - { - dataRole.push_back("Image"); - } - else - { - dataRole.resize(num); - for (n = 0; n < num; n++) - { - dataRole[n] = std::string(img_attrib->as_str(GADGETRON_DATA_ROLE, n)); - } - } - - long imageNumber = img_attrib->as_long(GADGETRON_IMAGENUMBER, 0); - - long slc, con, phs, rep, set, ave; - slc = m1->getObjectPtr()->slice; - con = m1->getObjectPtr()->contrast; - phs = m1->getObjectPtr()->phase; - rep = m1->getObjectPtr()->repetition; - set = m1->getObjectPtr()->set; - ave = m1->getObjectPtr()->average; - - std::ostringstream ostr; - - for (n = 0; n < dataRole.size(); n++) - { - ostr << dataRole[n] << "_"; - } - - ostr << "SLC" << slc << "_" - << "CON" << con << "_" - << "PHS" << phs << "_" - << "REP" << rep << "_" - << "SET" << set << "_" - << "AVE" << ave << "_" - << imageNumber; - - filename = ostr.str(); - } - else - { - std::ostringstream ostr; - ostr << "Image_" << m1->getObjectPtr()->image_index << "_" << m1->getObjectPtr()->image_series_index; - filename = ostr.str(); - } - - GadgetContainerMessage* mfilename = new GadgetContainerMessage(); - *(mfilename->getObjectPtr()) = filename; - - // -------------------------------------------------- - - unsigned short series_number = m1->getObjectPtr()->image_series_index + 1; - - // Try to find an already-generated Series Instance UID in our map - std::map::iterator it = seriesIUIDs.find(series_number); - - if (it == seriesIUIDs.end()) { - // Didn't find a Series Instance UID for this series number - char prefix[32]; - char newuid[96]; - if (seriesIUIDRoot.length() > 20) { - memcpy(prefix, seriesIUIDRoot.c_str(), 20); - prefix[20] = '\0'; - dcmGenerateUniqueIdentifier(newuid, prefix); - } - else { - dcmGenerateUniqueIdentifier(newuid); - } - seriesIUIDs[series_number] = std::string(newuid); - } - - // -------------------------------------------------- - - if(m3) - { - Gadgetron::write_ismrmd_image_into_dicom(*m1->getObjectPtr(), *m2->getObjectPtr(), xml, *m3->getObjectPtr(), seriesIUIDs[series_number], dcmFile); - } - else - { - ISMRMRD::MetaContainer attrib; - Gadgetron::write_ismrmd_image_into_dicom(*m1->getObjectPtr(), *m2->getObjectPtr(), xml, attrib, seriesIUIDs[series_number], dcmFile); - } - - // -------------------------------------------------- - /* release the old data array */ - m2->cont(NULL); // still need m3 - m1->release(); - - GadgetContainerMessage* mdcm = new GadgetContainerMessage(); - - *mdcm->getObjectPtr() = dcmFile; - mdcm->cont(mfilename); - - if (m3) - { - mfilename->cont(m3); - } - - this->next()->putq(mdcm); - - return GADGET_OK; - } - - private: - ISMRMRD::IsmrmrdHeader xml; - DcmFileFormat dcmFile; - std::string seriesIUIDRoot; - long initialSeriesNumber; - std::map seriesIUIDs; - }; - -} /* namespace Gadgetron */ - -#endif // DICOMFINISHGADGET_H diff --git a/gadgets/dicom/DicomImageWriter.cpp b/gadgets/dicom/DicomImageWriter.cpp deleted file mode 100644 index 0999fdaa0..000000000 --- a/gadgets/dicom/DicomImageWriter.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include - -// Gadgetron includes -#include "DicomImageWriter.h" -#include "GadgetContainerMessage.h" -#include "hoNDArray.h" -#include "ismrmrd/meta.h" - -// DCMTK includes -#define INCLUDE_CSTDLIB -#define INCLUDE_CSTDIO -#define INCLUDE_CSTRING -#define NOGDI -#include "dcmtk/config/osconfig.h" -#include "dcmtk/ofstd/ofstdinc.h" - -#include "dcmtk/dcmdata/dcostrmb.h" -#include "dcmtk/dcmdata/dctk.h" - - -namespace Gadgetron { - void DicomImageWriter::serialize(std::ostream& stream, const DcmFileFormat& dcmInput, - const std::optional& dcm_filename_message, - const std::optional& dcm_meta_message) { - - auto dcmFile = DcmFileFormat(dcmInput); //Copy here, because DCMTK has decided that the const keyword is bad - // Initialize transfer state of DcmDataset - dcmFile.transferInit(); - - // Calculate size of DcmFileFormat and create a SUFFICIENTLY sized buffer - long buffer_length = dcmFile.calcElementLength(EXS_LittleEndianExplicit, EET_ExplicitLength) * 2; - std::vector bufferChar(buffer_length); - char* buffer = &bufferChar[0]; - - DcmOutputBufferStream out_stream(buffer, buffer_length); - - OFCondition status; - - status = dcmFile.write(out_stream, EXS_LittleEndianExplicit, EET_ExplicitLength, NULL); - - offile_off_t serialized_length = 0; - - char* serialized; - out_stream.flushBuffer(reinterpret_cast(serialized), serialized_length); - - // finalize transfer state of DcmDataset - dcmFile.transferEnd(); - - - Core::IO::write(stream, GADGET_MESSAGE_DICOM_WITHNAME); - - uint32_t nbytes = (uint32_t)serialized_length; - Core::IO::write(stream, nbytes); - - stream.write(serialized, serialized_length); - - // check whether the image filename is attached - if (dcm_filename_message) { - unsigned long long len = dcm_filename_message->length(); - Core::IO::write_string_to_stream(stream, *dcm_filename_message); - } else { - Core::IO::write(stream, (unsigned long long)0); - } - - if (dcm_meta_message) { - std::stringstream str; - ISMRMRD::serialize(*dcm_meta_message, str); - std::string attribContent = str.str(); - Core::IO::write_string_to_stream(stream, attribContent); - } else { - Core::IO::write(stream, (unsigned long long)0); - } - - } - GADGETRON_WRITER_EXPORT(DicomImageWriter) -} /* namespace Gadgetron */ diff --git a/gadgets/dicom/DicomImageWriter.h b/gadgets/dicom/DicomImageWriter.h deleted file mode 100644 index aefad8851..000000000 --- a/gadgets/dicom/DicomImageWriter.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef DICOMIMAGEWRITER_H -#define DICOMIMAGEWRITER_H - -#include -#include "ismrmrd/ismrmrd.h" -#include "Writer.h" - -namespace Gadgetron { - - class DicomImageWriter - : public Core::TypedWriter, std::optional> { - protected: - void serialize(std::ostream& stream, const DcmFileFormat&, - const std::optional&, - const std::optional& args) override; - - protected: - public: - }; - -} /* namespace Gadgetron */ - -#endif diff --git a/gadgets/dicom/dicom.xml b/gadgets/dicom/dicom.xml deleted file mode 100644 index 20ae0f0b5..000000000 --- a/gadgets/dicom/dicom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - RemoveROOversampling - pingvin_mricore - RemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - trigger_dimension - repetition - - - sorting_dimension - slice - - - - - Buff - pingvin_mricore - BucketToBufferGadget - - N_dimension - - - - S_dimension - - - - split_slices - true - - - - - FFT - pingvin_mricore - FFTGadget - - - - Combine - pingvin_mricore - CombineGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - DicomFinish - pingvin_dicom - DicomFinishGadget - - - diff --git a/gadgets/dicom/dicom_ismrmrd_utility.cpp b/gadgets/dicom/dicom_ismrmrd_utility.cpp deleted file mode 100644 index d8930eab2..000000000 --- a/gadgets/dicom/dicom_ismrmrd_utility.cpp +++ /dev/null @@ -1,972 +0,0 @@ -/** \file dicom_ismrmrd_utility.cpp - \brief Implement some utility functions to convert ismrmrd image into dicom image - \author Hui Xue -*/ - -#include "dicom_ismrmrd_utility.h" -#include -#include -#include -#include "boost/date_time/gregorian/gregorian.hpp" - -namespace Gadgetron -{ - void write_dcm_string(DcmDataset *dataset, DcmTagKey& key, const char* s) - { - OFCondition status = dataset->putAndInsertString(key, s); - if (!status.good()) - { - GDEBUG("Failed to insert DICOM field (0x%04X,0x%04X) at line %u\n", key.getGroup(), key.getElement(), __LINE__); - GADGET_THROW("write_dcm_string failed ... "); - } - } - - void fill_dicom_image_from_ismrmrd_header(const ISMRMRD::IsmrmrdHeader& h, DcmFileFormat& dcmFile) - { - try - { - OFCondition status; - DcmTagKey key; - long BUFSIZE = 1024; - std::vector bufVec(BUFSIZE); - char *buf = &bufVec[0]; - - // Ensure DICOM dictionary is loaded - if (!dcmDataDict.isDictionaryLoaded()) - { - GADGET_THROW("Dictionary not loaded! Set DCMDICTPATH"); - } - - // ------------------------------------------------- - - ISMRMRD::ExperimentalConditions exp_cond = h.experimentalConditions; - - // ------------------------------------------------- - - ISMRMRD::SubjectInformation patient_info = *h.subjectInformation; - if(!h.subjectInformation.is_present() || !h.subjectInformation.get().patientName.is_present()) - patient_info.patientName.set("XXXXXXXX"); - - if(!h.subjectInformation.is_present() || !h.subjectInformation.get().patientWeight_kg.is_present()) - patient_info.patientWeight_kg.set(1000); - - if(!h.subjectInformation.is_present() || !h.subjectInformation.get().patientID.is_present()) - patient_info.patientID.set("XXXXXXXX"); - - if(!h.subjectInformation.is_present() || !h.subjectInformation.get().patientBirthdate.is_present()) - patient_info.patientBirthdate.set("1900-01-01"); - - if(!h.subjectInformation.is_present() || !h.subjectInformation.get().patientGender.is_present()) - patient_info.patientGender.set("o"); - - // ------------------------------------------------- - - ISMRMRD::StudyInformation study_info = *h.studyInformation; - - if(!h.studyInformation.is_present() || !h.studyInformation.get().studyDate.is_present()) - study_info.studyDate.set("1900-01-01"); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().studyTime.is_present()) - study_info.studyTime.set("12:12:12"); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().studyID.is_present()) - study_info.studyID.set("XXXXXXXX"); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().accessionNumber.is_present()) - study_info.accessionNumber.set(0); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().referringPhysicianName.is_present()) - study_info.referringPhysicianName.set("XXXXXXXX"); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().studyDescription.is_present()) - study_info.studyDescription.set("XXXXXXXX"); - - if(!h.studyInformation.is_present() || !h.studyInformation.get().studyInstanceUID.is_present()) - study_info.studyInstanceUID.set("XXXXXXXX"); - - // ------------------------------------------------- - - if (!h.measurementInformation) { - GWARN("Header missing MeasurementInformation parameters"); - } - - auto meas_info = h.measurementInformation; - - // ------------------------------------------------- - - if (!h.acquisitionSystemInformation) { - GWARN("Header missing AcquisitionSystemInformation parameters"); - } - - auto sys_info = h.acquisitionSystemInformation; - - if (!h.sequenceParameters) { - GWARN("Header missing SequenceTiming parameters"); - } - - // ------------------------------------------------- - - auto seq_info = h.sequenceParameters; - - if (h.encoding.size() == 0) { - GDEBUG_STREAM("Number of encoding spaces: " << h.encoding.size()); - GADGET_THROW("Encoding description is required"); - } - - // ------------------------------------------------- - - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - - // ------------------------------------------------- - - DcmDataset *dataset = dcmFile.getDataset(); - DcmMetaInfo *metainfo = dcmFile.getMetaInfo(); - - // Set the Application Entity Title in the DICOM Meta Info section - // The rest of the Meta Info will be automatically populated by DCMTK - if (sys_info && sys_info->stationName) { - status = metainfo->putAndInsertString(DcmTagKey(0x0002, 0x0016), - sys_info.get().stationName->c_str()); - if (!status.good()) { - GADGET_THROW("Failed to set AET in MetaInfo"); - } - } - else { - status = metainfo->putAndInsertString(DcmTagKey(0x0002, 0x0016), "none"); - if (!status.good()) { - GADGET_THROW("Failed to set AET in MetaInfo"); - } - } - - // Group Length - key.set(0x0008, 0x0000); - status = dataset->insertEmptyElement(key); - if (status.bad()) { - GADGET_THROW("Failed to write 0x0008 Group Length"); - } - - // Specific Character Set - key.set(0x0008, 0x0005); - write_dcm_string(dataset, key, "ISO_IR 192"); - - // Image Type - // ORIGINAL or DERIVED describes origin of pixel data - // PRIMARY or SECONDARY describes image creation time (during or after exam) - // OTHER, etc. are implementation-specific - key.set(0x0008, 0x0008); - write_dcm_string(dataset, key, "ORIGINAL\\PRIMARY\\OTHER"); - - // SOPClassUID - key.set(0x0008, 0x0016); - write_dcm_string(dataset, key, UID_MRImageStorage); - - // Study Date - if (study_info.studyDate) { - key.set(0x0008, 0x0020); - std::string d(study_info.studyDate.get()); - d.erase(std::remove(d.begin(), d.end(), '-'), d.end()); // erase all occurrences of '-' - write_dcm_string(dataset, key, d.c_str()); - } - - // Series, Acquisition, Content Date - if (meas_info && meas_info->seriesDate) { - key.set(0x0008, 0x0021); - std::string d(meas_info.get().seriesDate.get()); - d.erase(std::remove(d.begin(), d.end(), '-'), d.end()); - write_dcm_string(dataset, key, d.c_str()); - - key.set(0x0008, 0x0022); - write_dcm_string(dataset, key, d.c_str()); - - key.set(0x0008, 0x0023); - write_dcm_string(dataset, key, d.c_str()); - } - - // Study Time - if (study_info.studyTime) { - key.set(0x0008, 0x0030); - std::string t(study_info.studyTime.get()); - t.erase(std::remove(t.begin(), t.end(), ':'), t.end()); - write_dcm_string(dataset, key, t.c_str()); - } - - // Series, Acquisition, Content Time - if (meas_info->seriesTime) { - key.set(0x0008, 0x0031); - std::string t(meas_info.get().seriesTime.get()); - t.erase(std::remove(t.begin(), t.end(), ':'), t.end()); - write_dcm_string(dataset, key, t.c_str()); - - key.set(0x0008, 0x0032); - write_dcm_string(dataset, key, t.c_str()); - - key.set(0x0008, 0x0033); - write_dcm_string(dataset, key, t.c_str()); - } - - // Accession Number - key.set(0x0008, 0x0050); - if (study_info.accessionNumber) { - snprintf(buf, BUFSIZE, "%+" PRId64, *study_info.accessionNumber); - write_dcm_string(dataset, key, buf); - } - else { - const char* p = NULL; - write_dcm_string(dataset, key, p); - } - - // Modality - // TODO: this is hardcoded!! - key.set(0x0008, 0x0060); - write_dcm_string(dataset, key, "MR"); - - // Manufacturer - key.set(0x0008, 0x0070); - if (sys_info && sys_info->systemVendor) { - write_dcm_string(dataset, key, sys_info.get().systemVendor->c_str()); - } - else { - write_dcm_string(dataset, key, "UNKNOWN"); - } - - // Institution Name - key.set(0x0008, 0x0080); - if (sys_info && sys_info->institutionName) { - write_dcm_string(dataset, key, sys_info.get().institutionName->c_str()); - } - else { - write_dcm_string(dataset, key, "UNKNOWN"); - } - - // Referring Physician's Name - key.set(0x0008, 0x0090); - if (study_info.referringPhysicianName) { - write_dcm_string(dataset, key, study_info.referringPhysicianName->c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Station Name - key.set(0x0008, 0x1010); - if (sys_info && sys_info->stationName) { - write_dcm_string(dataset, key, sys_info.get().stationName->c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Study Description - key.set(0x0008, 0x1030); - if (study_info.studyDescription) { - write_dcm_string(dataset, key, study_info.studyDescription->c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Series Description - key.set(0x0008, 0x103E); - if (meas_info->seriesDescription) { - write_dcm_string(dataset, key, meas_info.get().seriesDescription->c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Manufacturer's Model Name - key.set(0x0008, 0x1090); - if (sys_info && sys_info->systemModel) { - write_dcm_string(dataset, key, sys_info.get().systemModel->c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Referenced SOP Instance UIDs - std::vector refs(meas_info->referencedImageSequence); - if (refs.size() > 0) { - DcmItem *ref_sequence; - std::vector::iterator it; - for (it = refs.begin(); it != refs.end(); ++it) { - std::string ref_uid(it->referencedSOPInstanceUID); - if (ref_uid.length() > 0) { // Only write non-empty strings - if (dataset->findOrCreateSequenceItem(key, ref_sequence, -2).good()) { - // Write the Referenced SOPClassUID (MRImageStorage) - key.set(0x0008, 0x1150); - ((DcmDataset *)ref_sequence)->putAndInsertString(key, UID_MRImageStorage); - // Write the Referenced SOPInstanceUID - key.set(0x0008, 0x1155); - ((DcmDataset *)ref_sequence)->putAndInsertString(key, ref_uid.c_str()); - } - } - } - } - - // Group Length - key.set(0x0010, 0x0000); - status = dataset->insertEmptyElement(key); - if (!status.good()) { - GADGET_THROW("Failed to write 0x0010 Group Length"); - } - - // Patient Name - key.set(0x0010, 0x0010); - if (patient_info.patientName) { - write_dcm_string(dataset, key, patient_info.patientName->c_str()); - } - else { - write_dcm_string(dataset, key, "None"); - } - - // Patient ID - key.set(0x0010, 0x0020); - if (patient_info.patientID) { - write_dcm_string(dataset, key, patient_info.patientID->c_str()); - } - else { - write_dcm_string(dataset, key, "0"); - } - - // Patient Birthdate - key.set(0x0010, 0x0030); - if (patient_info.patientBirthdate) { - std::string d(patient_info.patientBirthdate.get()); - d.erase(std::remove(d.begin(), d.end(), '-'), d.end()); - write_dcm_string(dataset, key, d.c_str()); - } - else { - status = dataset->insertEmptyElement(key); - } - - // Patient Sex - key.set(0x0010, 0x0040); - if (patient_info.patientGender) { - std::string patientGenderUppercase = patient_info.patientGender.get(); - std::transform(patientGenderUppercase.begin(), patientGenderUppercase.end(), patientGenderUppercase.begin(), ::toupper); - - if (patientGenderUppercase == "M" || patientGenderUppercase == "F" || patientGenderUppercase == "O") { - write_dcm_string(dataset, key, patientGenderUppercase.c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - } - else { - write_dcm_string(dataset, key, ""); - } - - // Patient Age - key.set(0x0010, 0x1010); - if (patient_info.patientBirthdate && meas_info->seriesDate) { - boost::gregorian::date bday(boost::gregorian::from_simple_string(patient_info.patientBirthdate.get())); - boost::gregorian::date seriesDate(boost::gregorian::from_simple_string(meas_info.get().seriesDate.get())); - - boost::gregorian::days age = seriesDate - bday; - - long age_in_years = age.days() / 365; - - snprintf(buf, BUFSIZE, "%03ldY", age_in_years); - write_dcm_string(dataset, key, buf); - } - else { - write_dcm_string(dataset, key, "000Y"); - } - - // Patient Weight - key.set(0x0010, 0x1030); - if (patient_info.patientWeight_kg) { - snprintf(buf, BUFSIZE, "%f", *patient_info.patientWeight_kg); - write_dcm_string(dataset, key, buf); - } - else { - write_dcm_string(dataset, key, "0.0"); - } - - // Group Length - key.set(0x0018, 0x0000); - status = dataset->insertEmptyElement(key); - if (!status.good()) { - GADGET_THROW("Failed to write 0x0018 Group Length"); - } - - // Scanning Sequence, Sequence Variant, Scan Options, Acquisition Type - std::string scanningSequence("RM"); - std::string sequenceVariant("NONE"); - std::string scanOptions("NONE"); - std::string mrAcquisitionType("2D"); - if (h.userParameters) { - ISMRMRD::UserParameters user_params = h.userParameters.get(); - std::vector strings = user_params.userParameterString; - std::vector::iterator it; - - for (it = strings.begin(); it != strings.end(); ++it) { - if (it->name == "scanningSequence") { - scanningSequence = it->value; - } - else if (it->name == "sequenceVariant") { - sequenceVariant = it->value; - } - else if (it->name == "scanOptions") { - scanOptions = it->value; - } - else if (it->name == "mrAcquisitionType") { - mrAcquisitionType = it->value; - } - } - } - key.set(0x0018, 0x0020); - write_dcm_string(dataset, key, scanningSequence.c_str()); - key.set(0x0018, 0x0021); - write_dcm_string(dataset, key, sequenceVariant.c_str()); - key.set(0x0018, 0x0022); - write_dcm_string(dataset, key, scanOptions.c_str()); - key.set(0x0018, 0x0023); - write_dcm_string(dataset, key, mrAcquisitionType.c_str()); - - // Angio Flag - // TODO: hardcoded - key.set(0x0018, 0x0025); - write_dcm_string(dataset, key, "N"); - - // Slice Thickness - // This will need updated if the "reconSpace.fieldOfView_mm.z" field - // is changed in the ISMRMRD populating code (client) - if (r_space.matrixSize.z == 0) r_space.matrixSize.z = 1; - key.set(0x0018, 0x0050); - snprintf(buf, BUFSIZE, "%f", r_space.fieldOfView_mm.z / r_space.matrixSize.z); - write_dcm_string(dataset, key, buf); - - // Spacing Between Slices - key.set(0x0018, 0x0088); - snprintf(buf, BUFSIZE, "%f", r_space.fieldOfView_mm.z); - write_dcm_string(dataset, key, buf); - - // Repetition Time - if (seq_info && seq_info.get().TR.is_present() && seq_info.get().TR.get().size() > 0) - { - key.set(0x0018, 0x0080); - snprintf(buf, BUFSIZE, "%f", seq_info.get().TR.get().front()); - write_dcm_string(dataset, key, buf); - } - - // Echo Time - if (seq_info && seq_info.get().TE.is_present() && seq_info.get().TE.get().size() > 0) - { - key.set(0x0018, 0x0081); - snprintf(buf, BUFSIZE, "%f", seq_info.get().TE.get().front()); - write_dcm_string(dataset, key, buf); - } - - // Inversion Time - if (seq_info && seq_info.get().TI.is_present() && seq_info.get().TI.get().size()>0) - { - key.set(0x0018, 0x0082); - snprintf(buf, BUFSIZE, "%f", seq_info.get().TI.get().front()); - write_dcm_string(dataset, key, buf); - } - - // Flip Angle - if (seq_info && seq_info.get().flipAngle_deg.is_present() && seq_info.get().flipAngle_deg.get().size()>0) - { - key.set(0x0018, 0x1314); - snprintf(buf, BUFSIZE, "%ld", (long)seq_info.get().flipAngle_deg.get().front()); - write_dcm_string(dataset, key, buf); - } - - // Imaging Frequency in tenths of MHz ??? - key.set(0x0018, 0x0084); - snprintf(buf, BUFSIZE, "%f", (float)exp_cond.H1resonanceFrequency_Hz / 10000000.); - write_dcm_string(dataset, key, buf); - - // Magnetic Field Strength (T) - key.set(0x0018, 0x0087); - if (sys_info && sys_info->systemFieldStrength_T) { - snprintf(buf, BUFSIZE, "%f", *sys_info->systemFieldStrength_T); - write_dcm_string(dataset, key, buf); - } - else { - write_dcm_string(dataset, key, "3.0"); - } - - key.set(0x0018, 0x0091); - // Echo Train Length - if (h.encoding[0].echoTrainLength) { - snprintf(buf, BUFSIZE, "%ld", (long)*h.encoding[0].echoTrainLength); - write_dcm_string(dataset, key, buf); - } - else { - write_dcm_string(dataset, key, "1"); - } - - // Percent Sampling - // TODO: hardcoded - key.set(0x0018, 0x0093); - write_dcm_string(dataset, key, "100"); - - // Percent Phase FOV - // TODO: hardcoded - key.set(0x0018, 0x0094); - write_dcm_string(dataset, key, "100"); - - // Protocol Name - if (meas_info && meas_info->protocolName) { - key.set(0x0018, 0x1030); - write_dcm_string(dataset, key, meas_info.get().protocolName.get().c_str()); - } - else { - write_dcm_string(dataset, key, ""); - } - - // Trigger Time - TODO: use Image Meta Data - key.set(0x0018, 0x1060); - write_dcm_string(dataset, key, "0.0"); - - // Reconstruction Diameter (FOV) - TODO: ? - key.set(0x0018, 0x1100); - - // Frequency Encoding Direction - TODO: use Image Meta Data - key.set(0x0018, 0x1312); - write_dcm_string(dataset, key, "ROW"); - - if (meas_info) { - // Patient Position - key.set(0x0018, 0x5100); - write_dcm_string(dataset, key, meas_info.get().patientPosition.c_str()); - } - /****************************************/ - // Group Length - key.set(0x0020, 0x0000); - status = dataset->insertEmptyElement(key); - if (!status.good()) { - GADGET_THROW("Failed to write 0x0020 Group Length"); - } - - // Study Instance UID - key.set(0x0020, 0x000D); - if (study_info.studyInstanceUID) { - write_dcm_string(dataset, key, study_info.studyInstanceUID->c_str()); - } - - // Study ID - if (study_info.studyID) { - key.set(0x0020, 0x0010); - write_dcm_string(dataset, key, study_info.studyID->c_str()); - } - else { - write_dcm_string(dataset, key, "0"); - } - - // Frame of Reference UID - if (meas_info && meas_info->frameOfReferenceUID) { - key.set(0x0020, 0x0052); - write_dcm_string(dataset, key, meas_info.get().frameOfReferenceUID->c_str()); - } - - /****************************************/ - // Group Length - key.set(0x0028, 0x0000); - status = dataset->insertEmptyElement(key); - if (!status.good()) { - GADGET_THROW("Failed to write 0x0028 Group Length"); - } - - // Samples Per Pixel - key.set(0x0028, 0x0002); - // TODO: hardcoded - write_dcm_string(dataset, key, "1"); - - // Photometric Interpretation - key.set(0x0028, 0x0004); - // TODO: hardcoded - write_dcm_string(dataset, key, "MONOCHROME2"); - - // Pixel Spacing (Array of len 2) - key.set(0x0028, 0x0030); - float pixel_spacing_X = r_space.fieldOfView_mm.x / r_space.matrixSize.x; - float pixel_spacing_Y = r_space.fieldOfView_mm.y / r_space.matrixSize.y; - snprintf(buf, BUFSIZE, "%.3f\\%.3f", pixel_spacing_X, pixel_spacing_Y); - write_dcm_string(dataset, key, buf); - - // Bits Allocated - key.set(0x0028, 0x0100); - write_dcm_string(dataset, key, "16"); - // Bits Stored - key.set(0x0028, 0x0101); - write_dcm_string(dataset, key, "16"); - // High Bit - key.set(0x0028, 0x0102); - write_dcm_string(dataset, key, "15"); - // Pixel Representation - key.set(0x0028, 0x0103); - write_dcm_string(dataset, key, "1"); - } - catch(...) - { - GADGET_THROW("Exceptions happened in fill_dicom_image_from_ismrmrd_header(...) ... "); - } - } - - template - uint16_t convert_to_uint16(T val) - { - T val_to_convert = val; - - if (std::is_floating_point::value) - { - val_to_convert = std::round(val); - } - - if (val_to_convert < 0 || val_to_convert > std::numeric_limits::max()) - { - const std::string exceptMsg = "Failed to convert " + std::to_string(val) + " to 16-bit unsigned integer because it is out of the range [0, 65535]"; - GADGET_THROW(exceptMsg); - } - - return static_cast(val_to_convert); - } - - template - void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile) - { - try - { - hoNDArray< uint16_t > data(m2.dimensions()); - - const T *src = m2.get_data_ptr(); - auto dst = data.get_data_ptr(); - - T min_pix_val, max_pix_val, sum_pix_val = 0; - if (m2.get_number_of_elements() > 0) - { - min_pix_val = src[0]; - max_pix_val = src[0]; - } - - for (unsigned long i = 0; i < m2.get_number_of_elements(); i++) - { - T pix_val = src[i]; - // search for minimum and maximum pixel values - if (pix_val < min_pix_val) min_pix_val = pix_val; - if (pix_val > max_pix_val) max_pix_val = pix_val; - sum_pix_val += pix_val / 4; // scale by 25% to avoid overflow - dst[i] = convert_to_uint16(pix_val); - } - T mean_pix_val = (T)((sum_pix_val * 4) / (T)data.get_number_of_elements()); - - unsigned int BUFSIZE = 1024; - std::vector bufVec(BUFSIZE); - char *buf = &bufVec[0]; - - OFCondition status; - DcmTagKey key; - DcmDataset *dataset = dcmFile.getDataset(); - - // Echo Number - // TODO: it is often the case the img->contrast is not properly set - // likely due to the allocated ISMRMRD::ImageHeader being uninitialized - key.set(0x0018, 0x0086); - snprintf(buf, BUFSIZE, "%d", m1.contrast); - write_dcm_string(dataset, key, buf); - - // Acquisition Matrix ... Image Dimensions - // Defined as: [frequency rows, frequency columns, phase rows, phase columns] - // But at this point in the gadget I don't know the frequency encode direction - key.set(0x0018, 0x1310); - uint16_t im_dim[4] = { 0, 0, 0, 0 }; - im_dim[1] = m1.matrix_size[0]; - im_dim[2] = m1.matrix_size[1]; - - status = dataset->putAndInsertUint16Array(key, im_dim, 4); - if (!status.good()) - { - GADGET_THROW("Failed to stuff image dimensions"); - } - - // Series Number - // Only write a number if the image_series_index is positive and non-zero - key.set(0x0020, 0x0011); - snprintf(buf, BUFSIZE, "%ld", (long int)m1.image_series_index); - write_dcm_string(dataset, key, buf); - - // Image Number - key.set(0x0020, 0x0013); - snprintf(buf, BUFSIZE, "%d", m1.image_index + 1); - write_dcm_string(dataset, key, buf); - - // Image Position (Patient) - float corner[3]; - - corner[0] = m1.position[0] - - (m1.field_of_view[0] / 2.0f) * m1.read_dir[0] - - (m1.field_of_view[1] / 2.0f) * m1.phase_dir[0]; - corner[1] = m1.position[1] - - (m1.field_of_view[0] / 2.0f) * m1.read_dir[1] - - (m1.field_of_view[1] / 2.0f) * m1.phase_dir[1]; - corner[2] = m1.position[2] - - (m1.field_of_view[0] / 2.0f) * m1.read_dir[2] - - (m1.field_of_view[1] / 2.0f) * m1.phase_dir[2]; - - key.set(0x0020, 0x0032); - snprintf(buf, BUFSIZE, "%.4f\\%.4f\\%.4f", corner[0], corner[1], corner[2]); - write_dcm_string(dataset, key, buf); - - // Image Orientation - // read_dir, phase_dir, and slice_dir were calculated in - // a DICOM/patient coordinate system, so just plug them in - key.set(0x0020, 0x0037); - snprintf(buf, BUFSIZE, "%.4f\\%.4f\\%.4f\\%.4f\\%.4f\\%.4f", - m1.read_dir[0], m1.read_dir[1], m1.read_dir[2], - m1.phase_dir[0], m1.phase_dir[1], m1.phase_dir[2]); - write_dcm_string(dataset, key, buf); - - // Slice Location - key.set(0x0020, 0x1041); - snprintf(buf, BUFSIZE, "%f", m1.position[2]); - write_dcm_string(dataset, key, buf); - - // Columns - key.set(0x0028, 0x0010); - snprintf(buf, BUFSIZE, "%d", m1.matrix_size[1]); - write_dcm_string(dataset, key, buf); - - // Rows - key.set(0x0028, 0x0011); - snprintf(buf, BUFSIZE, "%d", m1.matrix_size[0]); - write_dcm_string(dataset, key, buf); - - //Number of frames - if (m1.matrix_size[2] > 1){ //Only write if we have more than 1 frame - key.set(0x0028,0x0008); - snprintf(buf,BUFSIZE,"%d",m1.matrix_size[2]); - write_dcm_string(dataset, key,buf); - } - - // Simple windowing using pixel values calculated earlier... - int mid_pix_val = (int)(max_pix_val + min_pix_val) / 2; - int window_center = (int)(mid_pix_val + mean_pix_val) / 2; - int window_width_left = (int)(window_center - min_pix_val); - int window_width_right = (int)(max_pix_val - window_center); - int window_width = (window_width_right > window_width_left) ? - window_width_right : window_width_left; - - // Window Center - key.set(0x0028, 0x1050); - snprintf(buf, BUFSIZE, "%d", window_center); - write_dcm_string(dataset, key, buf); - - // Window Width - key.set(0x0028, 0x1051); - snprintf(buf, BUFSIZE, "%d", window_width); - write_dcm_string(dataset, key, buf); - - // ACR_NEMA_2C_VariablePixelDataGroupLength - key.set(0x7fe0, 0x0000); - status = dataset->insertEmptyElement(key); - if (!status.good()) { - GADGET_THROW("Failed to write 0x7fe0 Group Length"); - } - - // Pixel Data - if ((unsigned long)m1.matrix_size[0] * (unsigned long)m1.matrix_size[1]*(unsigned long)m1.matrix_size[2] != - data.get_number_of_elements()) { - GADGET_THROW("Mismatch in image dimensions and available data"); - } - key.set(0x7fe0, 0x0010); - status = dataset->putAndInsertUint16Array(key, data.get_data_ptr(), data.get_number_of_elements()); - if (!status.good()) { - GADGET_THROW("Failed to stuff Pixel Data"); - } - - // Series Instance UID = generated here - key.set(0x0020, 0x000E); - write_dcm_string(dataset, key, seriesIUID.c_str()); - - // At a minimum, to put the DICOM image back into the database, - // you must change the SOPInstanceUID. - key.set(0x0008, 0x0018); // SOPInstanceUID - const char *root = "1.2.840.113619.2.156"; - char newuid[65]; - dcmGenerateUniqueIdentifier(newuid, root); - write_dcm_string(dataset, key, newuid); - } - catch(...) - { - GADGET_THROW("Exceptions happened in write_ismrmd_image_into_dicom(...) ... "); - } - } - - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - - template - void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile) - { - try - { - Gadgetron::write_ismrmd_image_into_dicom(m1, m2, seriesIUID, dcmFile); - - DcmDataset *dataset = dcmFile.getDataset(); - DcmTagKey key; - - // --------------------------------------------------------------------- - // check the attrib and filling corresponding dicom fields - // --------------------------------------------------------------------- - - long BUFSIZE = 1024; - std::vector bufVec(BUFSIZE); - char *buf = &bufVec[0]; - - size_t n; - - // ---------------------------------- - // image comment - // ---------------------------------- - size_t N = attrib.length(GADGETRON_IMAGECOMMENT); - if(N>0) - { - std::string str(std::string(attrib.as_str(GADGETRON_IMAGECOMMENT, 0))); - for (n=1; n0) - { - std::string str(std::string(attrib.as_str(GADGETRON_SEQUENCEDESCRIPTION, 0))); - for (n=1; n 0 ) - { - double v = attrib.as_double(GADGETRON_IMAGE_ECHOTIME, 0); - - key.set(0x0018, 0x0081); - snprintf(buf, BUFSIZE, "%f", v); - write_dcm_string(dataset, key, buf); - } - else - { - if(h.sequenceParameters.is_present()) - { - if(h.sequenceParameters.get().TE.is_present()) - { - float v = h.sequenceParameters.get().TE.get()[0]; - - key.set(0x0018, 0x0081); - snprintf(buf, BUFSIZE, "%f", v); - write_dcm_string(dataset, key, buf); - } - } - } - - // ---------------------------------- - // Trigger Time - // ---------------------------------- - uint32_t ticks = m1.physiology_time_stamp[0]; - double millisec = ticks * 2.5; - if ( millisec > 0 && millisec<60000 ) - { - key.set(0x0018, 0x1060); - snprintf(buf, BUFSIZE, "%f", millisec); - write_dcm_string(dataset, key, buf); - } - - // ---------------------------------- - // TI - // ---------------------------------- - if ( attrib.length(GADGETRON_IMAGE_INVERSIONTIME) > 0 ) - { - double v = attrib.as_double(GADGETRON_IMAGE_INVERSIONTIME, 0); - - key.set(0x0018, 0x0082); - snprintf(buf, BUFSIZE, "%f", v); - write_dcm_string(dataset, key, buf); - } - else - { - if(h.sequenceParameters.is_present()) - { - if(h.sequenceParameters.get().TI.is_present()) - { - float v = h.sequenceParameters.get().TI.get()[0]; - - key.set(0x0018, 0x0082); - snprintf(buf, BUFSIZE, "%f", v); - write_dcm_string(dataset, key, buf); - } - } - } - - // ---------------------------------- - // WindowCenter, WindowWidth - // ---------------------------------- - if ( attrib.length(GADGETRON_IMAGE_WINDOWCENTER) > 0 ) - { - double v = attrib.as_double(GADGETRON_IMAGE_WINDOWCENTER, 0); - - key.set(0x0028, 0x1050); - snprintf(buf, BUFSIZE, "%d", (int)v); - write_dcm_string(dataset, key, buf); - } - - if ( attrib.length(GADGETRON_IMAGE_WINDOWWIDTH) > 0 ) - { - double v = attrib.as_double(GADGETRON_IMAGE_WINDOWWIDTH, 0); - - key.set(0x0028, 0x1051); - snprintf(buf, BUFSIZE, "%d", (int)v); - write_dcm_string(dataset, key, buf); - } - } - catch(...) - { - GADGET_THROW("Exceptions happened in write_ismrmd_image_into_dicom(attrib) ... "); - } - } - - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); -} diff --git a/gadgets/dicom/dicom_ismrmrd_utility.h b/gadgets/dicom/dicom_ismrmrd_utility.h deleted file mode 100644 index ab26fb8a3..000000000 --- a/gadgets/dicom/dicom_ismrmrd_utility.h +++ /dev/null @@ -1,47 +0,0 @@ -/** \file dicom_ismrmrd_utility.h - \brief Implement some utility functions to convert ismrmrd image into dicom image - \author Hui Xue -*/ - -#pragma once - -#include -#include -#include - -#include "Gadget.h" - -#include "dcmtk/config/osconfig.h" -#include "dcmtk/ofstd/ofstdinc.h" -#define INCLUDE_CSTDLIB -#define INCLUDE_CSTDIO -#define INCLUDE_CSTRING -#include "dcmtk/dcmdata/dctk.h" -#include "dcmtk/dcmdata/dcostrmb.h" - -#include "hoNDArray.h" -#include "hoNDImage.h" -#include "ismrmrd/meta.h" -#include "ismrmrd/ismrmrd.h" -#include "ismrmrd/xml.h" -#include "mri_core_def.h" - -namespace Gadgetron -{ - // -------------------------------------------------------------------------- - /// fill dicom image from ismrmrd header - // -------------------------------------------------------------------------- - void fill_dicom_image_from_ismrmrd_header(const ISMRMRD::IsmrmrdHeader& h, DcmFileFormat& dcmFile); - - // -------------------------------------------------------------------------- - /// write a key and its value into dicom image - // -------------------------------------------------------------------------- - void write_dcm_string(DcmDataset *dataset, DcmTagKey& key, const char* s); - - // -------------------------------------------------------------------------- - /// write ismrmrd image into a dcm image - // -------------------------------------------------------------------------- - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, std::string& seriesIUID, DcmFileFormat& dcmFile); - // with image attribute - template void write_ismrmd_image_into_dicom(const ISMRMRD::ImageHeader& m1, const hoNDArray& m2, ISMRMRD::IsmrmrdHeader& h, ISMRMRD::MetaContainer& attrib, std::string& seriesIUID, DcmFileFormat& dcmFile); -} diff --git a/gadgets/examples/CMakeLists.txt b/gadgets/examples/CMakeLists.txt index 3d481add1..1a9665f0a 100644 --- a/gadgets/examples/CMakeLists.txt +++ b/gadgets/examples/CMakeLists.txt @@ -25,19 +25,7 @@ install(TARGETS pingvin_examples COMPONENT main ) - install(FILES - config/external_connect_example.xml - config/external_equivalent_example.xml - config/external_example.xml - config/external_julia_acquisition_example.xml - config/external_matlab_acquisition_example.xml - config/external_matlab_bucket_example.xml - config/external_matlab_buffer_example.xml - config/external_matlab_tiny_example.xml - config/external_python_acquisition_example.xml - config/external_python_bucket_example.xml - config/external_python_buffer_example.xml config/parallel_bypass_example.xml config/stream_complex_to_float.xml config/stream_float_to_short.xml diff --git a/gadgets/examples/config/external_connect_example.xml b/gadgets/examples/config/external_connect_example.xml deleted file mode 100644 index 44914d849..000000000 --- a/gadgets/examples/config/external_connect_example.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - 2 - - - - - - - - - - - diff --git a/gadgets/examples/config/external_equivalent_example.xml b/gadgets/examples/config/external_equivalent_example.xml deleted file mode 100644 index b8eba4017..000000000 --- a/gadgets/examples/config/external_equivalent_example.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 2 - - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - pingvin_mricore - BucketToBufferGadget - - - - pingvin_mricore - SimpleReconGadget - - - - pingvin_mricore - ImageArraySplitGadget - - - - pingvin_mricore - ExtractGadget - - - diff --git a/gadgets/examples/config/external_example.xml b/gadgets/examples/config/external_example.xml deleted file mode 100644 index 343e55253..000000000 --- a/gadgets/examples/config/external_example.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - 2 - - - - - - - - - - - - - - - - - - - - - - Extract - pingvin_mricore - ExtractGadget - - - - Autoscale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/examples/config/external_julia_acquisition_example.xml b/gadgets/examples/config/external_julia_acquisition_example.xml deleted file mode 100644 index 24174cb15..000000000 --- a/gadgets/examples/config/external_julia_acquisition_example.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - 2 - - - - - - - - diff --git a/gadgets/examples/config/external_matlab_acquisition_example.xml b/gadgets/examples/config/external_matlab_acquisition_example.xml deleted file mode 100644 index 7caeb61da..000000000 --- a/gadgets/examples/config/external_matlab_acquisition_example.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - 2 - - - - - - - - - - - diff --git a/gadgets/examples/config/external_matlab_bucket_example.xml b/gadgets/examples/config/external_matlab_bucket_example.xml deleted file mode 100644 index 380b0b1dc..000000000 --- a/gadgets/examples/config/external_matlab_bucket_example.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - 2 - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - - - - - - diff --git a/gadgets/examples/config/external_matlab_buffer_example.xml b/gadgets/examples/config/external_matlab_buffer_example.xml deleted file mode 100644 index c83153965..000000000 --- a/gadgets/examples/config/external_matlab_buffer_example.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 2 - - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - pingvin_mricore - BucketToBufferGadget - - - - - - - - - diff --git a/gadgets/examples/config/external_matlab_tiny_example.xml b/gadgets/examples/config/external_matlab_tiny_example.xml deleted file mode 100644 index 481548cd4..000000000 --- a/gadgets/examples/config/external_matlab_tiny_example.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 2 - - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - pingvin_mricore - BucketToBufferGadget - - - - - - - - - diff --git a/gadgets/examples/config/external_python_acquisition_example.xml b/gadgets/examples/config/external_python_acquisition_example.xml deleted file mode 100644 index 83f78a9b3..000000000 --- a/gadgets/examples/config/external_python_acquisition_example.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - 2 - - - - - - - diff --git a/gadgets/examples/config/external_python_bucket_example.xml b/gadgets/examples/config/external_python_bucket_example.xml deleted file mode 100644 index f1c432dbb..000000000 --- a/gadgets/examples/config/external_python_bucket_example.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - 2 - - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - - - - - diff --git a/gadgets/examples/config/external_python_buffer_example.xml b/gadgets/examples/config/external_python_buffer_example.xml deleted file mode 100644 index abddd6e59..000000000 --- a/gadgets/examples/config/external_python_buffer_example.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 2 - - - - pingvin_mricore - NoiseAdjustGadget - - - - pingvin_mricore - RemoveROOversamplingGadget - - - - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - - - - pingvin_mricore - BucketToBufferGadget - - - - - - - - - diff --git a/gadgets/fatwater/CMakeLists.txt b/gadgets/fatwater/CMakeLists.txt deleted file mode 100644 index 989db815f..000000000 --- a/gadgets/fatwater/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -add_library(pingvin_fatwater SHARED - FatWaterGadget.h FatWaterGadget.cpp -) - -set_target_properties(pingvin_fatwater PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries( - pingvin_fatwater - pingvin_core - pingvin_mricore - pingvin_toolbox_cpucore - pingvin_toolbox_cpufft - pingvin_toolbox_cpucore_math - pingvin_toolbox_log - pingvin_toolbox_fatwater -) - -install(FILES - FatWaterGadget.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - - install(TARGETS pingvin_fatwater - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - - -install(FILES - config/Generic_Cartesian_Grappa_FatWater.xml - DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/fatwater/FatWaterGadget.cpp b/gadgets/fatwater/FatWaterGadget.cpp deleted file mode 100644 index b12d5ff93..000000000 --- a/gadgets/fatwater/FatWaterGadget.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "FatWaterGadget.h" -#include "fatwater.h" -#include "mri_core_def.h" -#include -#include "correct_frequency_shift.h" - -namespace Gadgetron { - - using namespace std::complex_literals; - - FatWaterGadget::FatWaterGadget() { - - } - - int FatWaterGadget::process_config(ACE_Message_Block *mb) { - ISMRMRD::IsmrmrdHeader hdr; - ISMRMRD::deserialize(mb->rd_ptr(), hdr); - - if (hdr.sequenceParameters.is_present()) { - if (hdr.sequenceParameters->TE.is_present()) { - for (auto &te: *(hdr.sequenceParameters->TE)) { - this->echoTimes_.push_back(te * 1e-3); - } - } else { - GERROR("No echo times found in sequence parameters\n"); - return GADGET_FAIL; - } - } else { - GERROR("Sequence parameters are required to do water fat separations\n"); - return GADGET_FAIL; - } - - for (auto &te: echoTimes_) { - GDEBUG("Echo time: %f\n", te); - } - - if (hdr.acquisitionSystemInformation.is_present() && - hdr.acquisitionSystemInformation->systemFieldStrength_T.is_present()) { - this->fieldStrength_ = *(hdr.acquisitionSystemInformation->systemFieldStrength_T); - GDEBUG("Field strength: %f\n", this->fieldStrength_); - } else { - GERROR("Field strength not defined. Required for fat-water separation\n"); - return GADGET_FAIL; - } - - -// config.frequency_range = {range_frequency_offset.value()[0],range_frequency_offset.value()[1]}; - float omega = 1/(this->echoTimes_[1]-this->echoTimes_[0]); - config.frequency_range = {-omega,omega}; - config.lambda = regularization_lambda; - config.lambda_extra = regularization_offset; - config.number_of_frequency_samples = number_of_frequency_offsets; - config.r2_range = {range_r2star.value()[0],range_r2star.value()[1]}; - config.number_of_r2_samples = number_of_r2stars; - config.number_of_r2_fine_samples = number_of_r2stars_fine; - config.do_gradient_descent = do_gradient_descent; - config.downsamples = downsample_data; - - - return GADGET_OK; - } - - int FatWaterGadget::process(GadgetContainerMessage *m1) { - - GDEBUG("In FW process\n"); - - //Grab a reference to the buffer containing the imaging data - IsmrmrdImageArray &imagearr = *m1->getObjectPtr(); - - //7D, fixed order [X, Y, Z, CHA, N, S, LOC] - uint16_t X = imagearr.data_.get_size(0); - uint16_t Y = imagearr.data_.get_size(1); - uint16_t Z = imagearr.data_.get_size(2); - uint16_t CHA = imagearr.data_.get_size(3); - uint16_t N = imagearr.data_.get_size(4); - uint16_t S = imagearr.data_.get_size(5); - uint16_t LOC = imagearr.data_.get_size(6); - - FatWater::Parameters parameters; - - parameters.echo_times_s = this->echoTimes_; - - parameters.field_strength_T = this->fieldStrength_; - parameters.sample_time_us = sample_time_us; - - if (echoTimes_.size() < 3) { - GERROR("At least 3 echo times are required for fw separation\n"); - return GADGET_FAIL; - } - - FatWater::ChemicalSpecies water = {"water", {{1.0, 0.0}}}; - FatWater::ChemicalSpecies fat = {"fat", - { - {0.07960f - 0.0510if, -3.8415}, - {0.64660f , -3.4860}, - {0.09570f + 0.0140if, -2.7583}, - {-0.0047f - 0.0221if, -1.8762}, - {0.01600f - 0.0150if, -0.5047}, - {0.08490f - 0.0244if, 0.5260} - }}; - -// FatWater::ChemicalSpecies fat = {"fat", -// { -// {0.048, 5.3-4.7}, -// {0.039 , 4.31-4.7}, -// {0.004, 2.76-4.7}, -// {0.128, 2.1-4.7}, -// {0.693, 1.3-4.7}, -// {0.087, 0.9-4.7} -// }}; - parameters.species = {water, fat}; - - - //try { - //This should return the images - auto output = FatWater::fatwater_separation(imagearr.data_, parameters, config); - auto& wfimages = output.images; - auto& field_map = output.field_map; - auto& r2star_map = output.r2star_map; - - if (sample_time_us > 0){ - correct_frequency_shift(wfimages,parameters); - } - - //Now let's make an image array to return the f/w images + any additional recon products - //Right now, we will be using a copy of the original data - //TODO: Remove this data copy - //wfimages = imagearr.data_; - - uint16_t n_images = wfimages.get_size(4); - uint16_t s_images = wfimages.get_size(5); //S-dimention is the image dimension - uint16_t loc_images = wfimages.get_size(6); - - if (n_images != N || loc_images != LOC) { - GERROR("Wrong number of N or LOC images received from fat water separation\n"); - m1->release(); - return GADGET_FAIL; - } - - - GadgetContainerMessage *m2 = FatWaterImageArray(parameters, std::move(wfimages), - m1->getObjectPtr()->headers_, - m1->getObjectPtr()->meta_); - - if (this->next()->putq(m2) < 0) { - m1->release(); - m2->release(); - return GADGET_FAIL; - } - - - if (save_field_map) { - GadgetContainerMessage *m3 = MakeImageMessage(parameters, std::move(field_map), - m1->getObjectPtr()->headers_, m1->getObjectPtr()->headers_[0].image_series_index+200); - if (this->next()->putq(m3) < 0){ - m3->release(); - return GADGET_FAIL; - } - } - - if (save_r2star_map) { - GadgetContainerMessage *m3 = MakeImageMessage(parameters, std::move(r2star_map), - m1->getObjectPtr()->headers_, m1->getObjectPtr()->headers_[0].image_series_index+400); - if (this->next()->putq(m3) < 0){ - m3->release(); - return GADGET_FAIL; - } - } - - //Pass the image down the chain - if (this->next()->putq(m1) < 0) { - return GADGET_FAIL; - } - - return GADGET_OK; - - } - - GadgetContainerMessage * -FatWaterGadget::FatWaterImageArray(const FatWater::Parameters ¶meters, hoNDArray > &&wfimages, - const hoNDArray &headers, - const std::vector &metadata) const { - - - uint16_t n_images = wfimages.get_size(4); - uint16_t s_images = wfimages.get_size(5); //S-dimention is the image dimension - uint16_t loc_images = wfimages.get_size(6); - - auto m2 = new GadgetContainerMessage(); - m2->getObjectPtr()->data_ = std::move(wfimages); - m2->getObjectPtr()->headers_.create(n_images, s_images, loc_images); - for (uint16_t loc = 0; loc < loc_images; loc++) { - for (uint16_t s = 0; s < s_images; s++) { - for (uint16_t n = 0; n < n_images; n++) { - m2->getObjectPtr()->headers_[loc * s_images * n_images + s * n_images + - n] =headers[loc * s_images * n_images + - 0 * n_images + n]; - - m2->getObjectPtr()->headers_[loc * s_images * n_images + s * n_images + n].image_series_index = - m2->getObjectPtr()->headers_[loc * s_images * n_images + s * n_images + - n].image_series_index + 100; - - ISMRMRD::MetaContainer meta = metadata[loc * n_images * s_images + n]; - //TODO: These sepcies and image type specifiers should come from the toolbox - if (s < parameters.species.size()) { - if (parameters.species[s].name == "water") { - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_WATER); - } else if (parameters.species[s].name == "fat") { - meta.set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_FAT); - } - } else { - //TODO: What to call these images - } - m2->getObjectPtr()->meta_.push_back(meta); - } - } - } - return m2; - } - - GadgetContainerMessage * - FatWaterGadget::MakeImageMessage(FatWater::Parameters parameters, hoNDArray &&array, - const hoNDArray &headers, - uint16_t image_index) const { - - - auto image = new GadgetContainerMessage>(std::move(array)); - - auto header_message = new GadgetContainerMessage(headers[0]); - header_message->getObjectPtr()->data_type = ISMRMRD::ISMRMRD_FLOAT; - - header_message->getObjectPtr()->image_series_index = image_index; - - header_message->cont(image); - - return header_message; - } - - GADGET_FACTORY_DECLARE(FatWaterGadget) -} diff --git a/gadgets/fatwater/FatWaterGadget.h b/gadgets/fatwater/FatWaterGadget.h deleted file mode 100644 index 9aac23a2d..000000000 --- a/gadgets/fatwater/FatWaterGadget.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef FATWATERGADGET_H -#define FATWATERGADGET_H - -#include -#include "Gadget.h" -#include "hoNDArray.h" - -#include "vector_td_io.h" -namespace Gadgetron{ - - class FatWaterGadget : - public Gadget1 - { - public: - FatWaterGadget(); - - using value_range = vector_td; - -// GADGET_PROPERTY(range_frequency_offset,value_range , "Range of field map values in Hz", value_range(-500,500)); - GADGET_PROPERTY(number_of_frequency_offsets,unsigned int, "Number of field map strengths", 200); - GADGET_PROPERTY(range_r2star,value_range,"Range of R2* values in Hz",value_range(5,500)); - GADGET_PROPERTY(number_of_r2stars,unsigned int, "Number of R2* value to use during graph-cut",5); - GADGET_PROPERTY(number_of_r2stars_fine,unsigned int,"Number of R2* values used for refinement after graph-cut",200); - GADGET_PROPERTY(graph_cut_iterations,unsigned int, "Number of graph cut iterations to run",40); - GADGET_PROPERTY(regularization_lambda,float,"Strength of the spatial regularization",0.02); - GADGET_PROPERTY(regularization_offset,float, "Fixed value to add to the regularization for increased smoothness in low signal areas",0.01); - GADGET_PROPERTY(do_gradient_descent, bool, "Use gradient descent after graph-cut",true); - GADGET_PROPERTY(downsample_data, unsigned int, "Number of times to downsample data before calculating the field map",0); - GADGET_PROPERTY(save_field_map , bool, "Save the field map",false); - GADGET_PROPERTY(save_r2star_map, bool, "Save the R2* map",false); - GADGET_PROPERTY(sample_time_us, float, "Sample time in microseconds for frequency offset correction. Set to 0 for disabled",0); - - - - protected: - virtual int process(GadgetContainerMessage* m1); - virtual int process_config(ACE_Message_Block* mb); - - - - - private: - std::vector echoTimes_; - float fieldStrength_; - FatWater::Config config; - - - GadgetContainerMessage * - FatWaterImageArray(const FatWater::Parameters ¶meters, hoNDArray > &&wfimages, - const hoNDArray &headers, - const std::vector &metadata) const; - - GadgetContainerMessage * - MakeImageMessage(FatWater::Parameters parameters, hoNDArray &&array, - const hoNDArray &header, uint16_t image_index) const; - }; -} -#endif //FATWATERGADGET_H diff --git a/gadgets/fatwater/config/Generic_Cartesian_Grappa_FatWater.xml b/gadgets/fatwater/config/Generic_Cartesian_Grappa_FatWater.xml deleted file mode 100644 index 9f5c1c496..000000000 --- a/gadgets/fatwater/config/Generic_Cartesian_Grappa_FatWater.xml +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimensioncontrast - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionrepetition - S_dimensioncontrast - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - - perform_timingtrue - verbosetrue - - - average_all_ref_Nfalse - - average_all_ref_Sfalse - - - - prepare_ref_alwaysfalse - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - - perform_timingtrue - verbosetrue - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres-1 - upstream_coil_compression_num_modesKept0 - - - - - - - - - - - - - - - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressionfalse - downstream_coil_compression_thres0.002 - downstream_coil_compression_num_modesKept0 - - - - perform_timingtrue - verbosetrue - - - send_out_gfactortrue - - - - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingFilterGadget - - - - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_filter_RO_width0.15 - partial_fourier_filter_E1_width0.15 - partial_fourier_filter_E2_width0.15 - partial_fourier_filter_densityCompfalse - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - Combiner - pingvin_mricore - ImageAccumulatorGadget - - accumulate_dimension - contrast - - - combine_along - S - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - - perform_timingfalse - verbosefalse - - - - - - FatWater - pingvin_fatwater - FatWaterGadget - number_of_frequency_offsets200 - range_r2star[5,144] - number_of_r2stars5 - number_of_r2stars_fine144 - graph_cut_iterations100 - do_gradient_descenttrue - regularization_lambda0.1 - regularization_offset0.01 - save_field_maptrue - save_r2star_maptrue - downsample_data1 - sample_time_us0 - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - - - - - - - - - - - - - - - diff --git a/gadgets/hyper/CMRT.xml b/gadgets/hyper/CMRT.xml deleted file mode 100644 index 4478c2d93..000000000 --- a/gadgets/hyper/CMRT.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - CMRT - pingvin_hyper - CMRTGadget - projections_per_recon128 - golden_ratiotrue - - - - Extract - pingvin_mricore - ExtractGadget - - - diff --git a/gadgets/hyper/CMRT3D.xml b/gadgets/hyper/CMRT3D.xml deleted file mode 100644 index e784d7967..000000000 --- a/gadgets/hyper/CMRT3D.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - NFFT - pingvin_hyper - NFFT2DGadget - - - - CMRT3S - pingvin_hyper - CMRT3DGadget - projections_per_recon128 - projections_percentage100 - golden_ratiotrue - - - - Extract - pingvin_mricore - ExtractGadget - - - diff --git a/gadgets/hyper/CMRT3DGadget.cpp b/gadgets/hyper/CMRT3DGadget.cpp deleted file mode 100644 index bc75ee309..000000000 --- a/gadgets/hyper/CMRT3DGadget.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "CMRT3DGadget.h" -#include "hoNDFFT.h" -#include "hoNDArray_utils.h" -#include "hoNDArray_fileio.h" -#include "cuNDArray_utils.h" -#include "cuNDArray_elemwise.h" -#include "cuNDArray_operators.h" -#include "cuNDArray_math.h" -#include "radial_utilities.h" -#include "vector_td_operators.h" -#include - -static const float alpha_ = 2.0f; // oversampling for radial NFFT. If to be changed, also change setup arguments -static const float W_ = 5.5f; // Kaiser-Bessel Window size for the radial NFFT -static const float readout_oversampling_factor_ = 1.0f; // There is no "readout" oversampling for the radial NFFT - -namespace Gadgetron { - -/** - * Expects ISMRMRD XML configuration - * - */ - -int CMRT3DGadget::process_config(ACE_Message_Block* mb) -{ - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - - if (h.encoding.size() != 1) { - GDEBUG("This Gadget only supports one encoding space\n"); - return GADGET_FAIL; - } - - ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; - - - // Matrix size x is the oversampled readout size : size FH*2 -- not for the hyperplarization? - // Matrix size y is the AP/RL size - - image_space_dimensions_3D_.push_back(e_space.matrixSize.y); - image_space_dimensions_3D_.push_back(e_space.matrixSize.y); - image_space_dimensions_3D_.push_back(e_space.matrixSize.x/*/2*/); - - GDEBUG("Matrix size: %d, %d, %d\n", - image_space_dimensions_3D_[0], - image_space_dimensions_3D_[1], - image_space_dimensions_3D_[2] ); - - num_projections_expected_ = projections_per_recon.value(); - projections_percentage_ =projections_percentage.value(); - num_projections_to_use_ = num_projections_expected_/(100/projections_percentage_); - - golden_ratio_ = golden_ratio.value(); - GDEBUG("Number of projections (expected/utilization percentage): %d/%d\n", num_projections_expected_, projections_percentage_ ); - GDEBUG("I.e. using %d projections for the reconstruction\n", num_projections_to_use_ ); - - std::vector dims; - dims.push_back(image_space_dimensions_3D_[0]); // number of samples per radial profile - dims.push_back(num_projections_to_use_); // number of radial profiles - dims.push_back(image_space_dimensions_3D_[2]); // number of slices - - buffer_ = boost::shared_ptr< cuNDArray< complext > >( new cuNDArray< complext >(dims) ); - - // Calculate trajectories and dcw for the radial NFFTs - // - - boost::shared_ptr< cuNDArray > traj = calculate_trajectory(); - boost::shared_ptr< cuNDArray > dcw = calculate_density_compensation(); - - - if( !traj.get() || !dcw.get() ){ - GDEBUG("Failed to initialize radial trajecotory/dcw\n"); - return GADGET_FAIL; - } - - // Setup radial NFFT encoding operator - // - - E_ = boost::make_shared< NFFTOperator >(); - - E_->set_dcw( dcw ); - - E_->setup( uint64d2(image_space_dimensions_3D_[0], image_space_dimensions_3D_[1]), - uint64d2(image_space_dimensions_3D_[0], image_space_dimensions_3D_[1])<<1, // !! <-- alpha_ - W_ ); - - - return GADGET_OK; -} - -int CMRT3DGadget::process(GadgetContainerMessage* m1, - GadgetContainerMessage< hoNDArray< std::complex > >* m2) -{ - // Check if we should ignore this image - // - to simulate undersampling in the number of slices - - if( (images_received_%(100/projections_percentage_)) != 0 ){ - // Ignore this image - images_received_++; - return GADGET_OK; - } - - // We will not pass along m2, so we can modify its array safely - // - - hoNDArray< std::complex > *host_image = m2->getObjectPtr(); - - // Some validity checks - // - - if( !(host_image->get_number_of_dimensions() == 2 || ( host_image->get_number_of_dimensions()==3 && host_image->get_size(2)==1 ))) { - GDEBUG("The input image has an unexpected number of dimensions\n", host_image->get_number_of_dimensions()); - return GADGET_FAIL; - } - - if( host_image->get_size(0) != image_space_dimensions_3D_[0] || - host_image->get_size(1) != image_space_dimensions_3D_[2] ){ - GDEBUG("The input image has unexpected dimensionality: %d %d %d %d\n", host_image->get_size(0), host_image->get_size(1), image_space_dimensions_3D_[0], image_space_dimensions_3D_[1] ); - return GADGET_FAIL; - } - - // Perform batched 1D FFTs along the phase encoding direction of the input image - // I.e. permute and then perform FFT - - - //*host_image = *permute( host_image, &order ); - hoNDFFT::instance()->fft( host_image, 0 ); - - // Next copy each line into the buffer - // - - GDEBUG("Received image #%d\n", images_received_); - - for( size_t row=0;rowget_size(1); row++ ){ - - size_t offset_in = - row*host_image->get_size(0); - - size_t offset_out = - row*host_image->get_size(0)*num_projections_to_use_+ - images_used_*host_image->get_size(0); - - if( cudaMemcpy( buffer_->get_data_ptr()+offset_out, - host_image->get_data_ptr()+offset_in, - host_image->get_size(0)*sizeof(complext), - cudaMemcpyHostToDevice ) != cudaSuccess ){ - GDEBUG("Upload to device for line %d failed\n", row); - return GADGET_FAIL; - } - } - - // Another image has been received and uploaded... - // - - images_received_++; - images_used_++; - - // When we are ready to perform reconstruction, do it... - // - - if( images_used_ == num_projections_to_use_ ){ - - auto traj = calculate_trajectory(tot_images_); - E_->preprocess( *traj ); - GDEBUG("\n\nPerforming reconstruction\n"); - - std::vector dims; - dims.push_back(image_space_dimensions_3D_[0]); - dims.push_back(image_space_dimensions_3D_[1]); - dims.push_back(image_space_dimensions_3D_[2]); - - cuNDArray< complext > result(dims); - - E_->mult_MH( buffer_.get(), &result ); - - /* - boost::shared_ptr< hoNDArray > > host_result = result.to_host(); - write_nd_array >(host_result.get(), "result.cplx"); - - boost::shared_ptr< hoNDArray > host_norm = abs(&result)->to_host(); - write_nd_array( host_norm.get(), "result.real" );*/ - - // Create new image header/image to pass along - // - - GadgetContainerMessage *m = - new GadgetContainerMessage(); - - GadgetContainerMessage< hoNDArray< std::complex > > *cm = - new GadgetContainerMessage< hoNDArray< std::complex > >(); - - *m->getObjectPtr() = *m1->getObjectPtr(); - m->cont(cm); - - // std::complex and Gadgetron::complext are binary compatible - boost::shared_ptr< hoNDArray< complext > > host_result = result.to_host(); - *cm->getObjectPtr() = *((hoNDArray< std::complex >*) host_result.get()); - - m->getObjectPtr()->matrix_size[0] = dims[0]; - m->getObjectPtr()->matrix_size[1] = dims[1]; - m->getObjectPtr()->matrix_size[2] = dims[2]; - m->getObjectPtr()->channels = 1; - m->getObjectPtr()->image_index = 1; - - if (this->next()->putq(m) < 0) { - GDEBUG("Failed to put result image on to queue\n"); - m->release(); - return GADGET_FAIL; - } - tot_images_ += images_used_; - images_used_ = 0; - } - - m1->release(); - return GADGET_OK; -} - -boost::shared_ptr< cuNDArray > -CMRT3DGadget::calculate_trajectory(unsigned int offset) -{ - // Define trajectories - - boost::shared_ptr< cuNDArray > traj; - if (golden_ratio_) - traj = compute_radial_trajectory_golden_ratio_2d - ( image_space_dimensions_3D_[0], num_projections_to_use_, 1,offset,GR_ORIGINAL ); - else - traj = compute_radial_trajectory_fixed_angle_2d - ( image_space_dimensions_3D_[0], num_projections_to_use_, 1 /*number of frames*/ ); - - if (!traj.get()) { - GDEBUG("Failed to compute radial trajectory"); - return boost::shared_ptr< cuNDArray >(); - } - - return traj; -} - -boost::shared_ptr< cuNDArray > -CMRT3DGadget::calculate_density_compensation() -{ - // Compute density compensation weights - boost::shared_ptr< cuNDArray > dcw; - - if (golden_ratio_) - dcw =compute_radial_dcw_golden_ratio_2d - ( image_space_dimensions_3D_[0], num_projections_to_use_, alpha_, 1.0f/readout_oversampling_factor_, GR_ORIGINAL ); - else - dcw =compute_radial_dcw_fixed_angle_2d - ( image_space_dimensions_3D_[0], num_projections_to_use_, alpha_, 1.0f/readout_oversampling_factor_ ); - - if (!dcw.get()) { - GDEBUG("Failed to compute density compensation weights\n"); - return boost::shared_ptr< cuNDArray >(); - } - - return dcw; -} - -GADGET_FACTORY_DECLARE(CMRT3DGadget) -} diff --git a/gadgets/hyper/CMRT3DGadget.h b/gadgets/hyper/CMRT3DGadget.h deleted file mode 100644 index ceb47a60a..000000000 --- a/gadgets/hyper/CMRT3DGadget.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "Gadget.h" -#include "hoNDArray.h" -#include "cuNDArray.h" -#include "complext.h" -#include "cuNFFT.h" -#include "NFFTOperator.h" - -#include -#include - -namespace Gadgetron { - - class CMRT3DGadget : - public Gadget2< ISMRMRD::ImageHeader, hoNDArray< std::complex > > - { - public: - CMRT3DGadget() : images_received_(0), images_used_(0), tot_images_(0) {}; - ~CMRT3DGadget() {}; - - protected: - - GADGET_PROPERTY(golden_ratio,bool,"Use golden ratio",false); - GADGET_PROPERTY(projections_per_recon,int,"Number of projections for each recon",16); - GADGET_PROPERTY(projections_percentage,float,"Percentage of projections to use",100); - - virtual int process_config(ACE_Message_Block* mb); - virtual int process(GadgetContainerMessage< ISMRMRD::ImageHeader > *m1, - GadgetContainerMessage< hoNDArray< std::complex > > *m2); - - virtual boost::shared_ptr< cuNDArray > calculate_trajectory(unsigned int offset=0); - virtual boost::shared_ptr< cuNDArray > calculate_density_compensation(); - - boost::shared_ptr< cuNDArray< complext > > buffer_; - boost::shared_ptr< NFFTOperator > E_; - std::vector image_space_dimensions_3D_; - unsigned int num_projections_expected_; - unsigned int num_projections_to_use_; - unsigned int projections_percentage_; - unsigned int images_received_; - unsigned int images_used_; - unsigned int tot_images_; - bool golden_ratio_; - }; -} diff --git a/gadgets/hyper/CMRTGadget.cpp b/gadgets/hyper/CMRTGadget.cpp deleted file mode 100644 index fc73a324a..000000000 --- a/gadgets/hyper/CMRTGadget.cpp +++ /dev/null @@ -1,444 +0,0 @@ -#include "CMRTGadget.h" -#include "cuNFFT.h" -#include "vector_td_utilities.h" -#include "permutationOperator.h" -#include "hoNDArray_utils.h" -#include "hoNDArray_fileio.h" -#include "cuNDArray_utils.h" -#include "cuNDArray_elemwise.h" -#include "cuNDArray_operators.h" -#include "radial_utilities.h" -#include "vector_td_operators.h" -#include "../../toolboxes/nfft/NFFTOperator.h" -#include "multiplicationOperatorContainer.h" -#include "cuCgSolver.h" -#include "cuTvOperator.h" -#include "lbfgsSolver.h" -#include "cuSbcCgSolver.h" -#include "cuPartialDerivativeOperator.h" -#include "cuPartialDerivativeOperator2.h" -#include -#include -#include "cuNlcgSolver.h" -#include - -#include -#include - -namespace Gadgetron{ - - -int CMRTGadget::process_config(ACE_Message_Block* mb) -{ - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - - if (h.encoding.size() != 1) { - GDEBUG("This Gadget only supports one encoding space\n"); - return GADGET_FAIL; - } - - ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; - - // Matrix size x is the oversampled readout size : size FH*2 -- not for the hyperplarization? - // Matrix size y is the AP/RL size - - image_space_dimensions_3D_.push_back(e_space.matrixSize.y); - image_space_dimensions_3D_.push_back(e_space.matrixSize.y); - image_space_dimensions_3D_.push_back(e_space.matrixSize.x/*/2*/); - - GDEBUG("Matrix size: %d, %d, %d\n", - image_space_dimensions_3D_[0], - image_space_dimensions_3D_[1], - image_space_dimensions_3D_[2] ); - - GDEBUG("Matrix size: %d, %d\n", e_space.matrixSize.x, e_space.matrixSize.y, e_space.matrixSize.z); - dimensions_.push_back(r_space.matrixSize.x); - dimensions_.push_back(r_space.matrixSize.y); - - field_of_view_.push_back(e_space.fieldOfView_mm.x); - field_of_view_.push_back(e_space.fieldOfView_mm.y); - GDEBUG("FOV: %f, %f\n", r_space.fieldOfView_mm.x, r_space.fieldOfView_mm.y); - - repetitions_ = e_limits.repetition.is_present() ? e_limits.repetition.get().maximum + 1 : 1; - GDEBUG("#Repetitions: %d\n", repetitions_); - - golden_ratio_ =golden_ratio.value(); - use_TV_ = use_TV.value(); - projections_per_recon_ = projections_per_recon.value(); - iterations_ = iterations.value(); - - return GADGET_OK; -} - -int CMRTGadget::process(GadgetContainerMessage< ISMRMRD::AcquisitionHeader > *m1, // header - GadgetContainerMessage< hoNDArray< std::complex > > *m2, // data - GadgetContainerMessage< hoNDArray > *m3 ) // traj/dcw -{ - // Throw away any noise samples if they have been allowed to pass this far down the chain... - // - - bool is_noise = m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT); - if (is_noise) { - m1->release(); - return GADGET_OK; - } - - // First pass initialization - // - - if (frame_readout_queue_.empty()) { - samples_per_readout_ = m1->getObjectPtr()->number_of_samples; - num_coils_ = m1->getObjectPtr()->active_channels; - dimensions_.push_back(m1->getObjectPtr()->active_channels); - dimensions_.push_back(repetitions_); - num_trajectory_dims_ = m3->getObjectPtr()->get_size(0); // 2 for trajectories only, 3 for both trajectories + dcw - } - - // Enqueue incoming readouts and trajectories - // - - frame_readout_queue_.push(std::unique_ptr(duplicate_array(m2))); - - //Only extract trajectories for first frame. Assume next frames are equal - if (frames.empty()) frame_traj_queue_.push(std::unique_ptr(duplicate_array(m3))); - - // If the last readout for a slice has arrived then perform a reconstruction - // - - bool is_last_scan_in_repetition = - m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_REPETITION); - - if (is_last_scan_in_repetition) { - num_frames++; - GDEBUG("FRAME # %d \n",num_frames); - // Get samples for frame - // - GDEBUG("Extracting samples \n"); - frames.push_back(extract_samples_from_queue(frame_readout_queue_)); - // Get trajectories/dcw for frame - Only for first frame - // - if (frames.size() == 1 ){ - extract_trajectory_and_dcw_from_queue(frame_traj_queue_, this->traj, this->dcw); - GDEBUG("Extracting trajectory \n"); - } - - bool is_last_scan_in_slice= m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_SLICE); - GDEBUG("Last scan in slice %i \n",is_last_scan_in_slice); - //If we have enough projections, get the show on the road - if (is_last_scan_in_slice ){ - GDEBUG("Framing %i frames \n",num_frames); - - if (num_frames%projections_per_recon_ != 0) { - GDEBUG("Number of frames must be divisible by number of projecitons"); - return GADGET_FAIL; - } - boost::shared_ptr > data = get_combined_frames(); - auto data_dims = data->get_dimensions(); - size_t ntimeframes = data_dims.back()/projections_per_recon_; - data_dims.back() = projections_per_recon_; - data_dims.push_back(ntimeframes); - data->reshape(data_dims); - // Initialize plan - // - GDEBUG("Data size: %i %i %i",data->get_size(0),data->get_size(1),data->get_size(2)); - boost::shared_ptr >cu_traj(new cuNDArray(*traj)); - - std::vector projection_dims; - projection_dims.push_back(dimensions_[0]*2); - projection_dims.push_back(dimensions_[1]); - - projection_dims.push_back(projections_per_recon_); - projection_dims.push_back(ntimeframes); - - - //cuNDArray result(&image_space_dimensions_3D_); - boost::shared_ptr > E(new CMRTOperator); - E->setup(cu_traj,image_space_dimensions_3D_,projection_dims,0,golden_ratio_); - - auto image_space_dimensions_4D = image_space_dimensions_3D_; - image_space_dimensions_4D.push_back(ntimeframes); - E->set_domain_dimensions(image_space_dimensions_4D); - E->set_codomain_dimensions(data->get_dimensions()); - - - boost::shared_ptr > result; - //cuCgSolver solver; - //cuNlcgSolver solver; - - if (use_TV_){ - cuSbcCgSolver solver; - solver.set_encoding_operator(E); - //solver.set_max_iterations(20); - solver.set_max_outer_iterations(iterations_); - solver.get_inner_solver()->set_max_iterations(10); - solver.set_tc_tolerance(1e-8f); - auto Rx1_ = boost::make_shared< cuPartialDerivativeOperator >(0); - - auto Ry1_ = boost::make_shared< cuPartialDerivativeOperator >(1); - auto Rz1_ = boost::make_shared< cuPartialDerivativeOperator >(2); - - auto Rt1_ = boost::make_shared< cuPartialDerivativeOperator2 >(); - - Rx1_->set_domain_dimensions(image_space_dimensions_4D); - Rx1_->set_codomain_dimensions(image_space_dimensions_4D); - - Ry1_->set_domain_dimensions(image_space_dimensions_4D); - Ry1_->set_codomain_dimensions(image_space_dimensions_4D); - - Rz1_->set_domain_dimensions(image_space_dimensions_4D); - Rz1_->set_codomain_dimensions(image_space_dimensions_4D); - - Rt1_->set_domain_dimensions(image_space_dimensions_4D); - Rt1_->set_codomain_dimensions(image_space_dimensions_4D); - float lambda = 2000; - float mu = 1000; - Rx1_ ->set_weight(lambda); - Ry1_ ->set_weight(lambda); - Rz1_ ->set_weight(lambda); - Rt1_->set_weight(lambda); - E->set_weight(mu); - solver.add_regularization_group_operator(Rx1_); - solver.add_regularization_group_operator(Ry1_); - solver.add_regularization_group_operator(Rz1_); - solver.add_regularization_group_operator(Rt1_); - solver.add_group(); - - solver.set_output_mode(cuCgSolver::OUTPUT_VERBOSE); - - result = solver.solve(data.get()); - } else { - cuCgSolver solver; - solver.set_encoding_operator(E); - solver.set_max_iterations(iterations_); - solver.set_tc_tolerance(1e-8f); - solver.set_output_mode(cuCgSolver::OUTPUT_VERBOSE); - - result = solver.solve(data.get()); - } - - size_t nelements3d = std::accumulate(image_space_dimensions_3D_.begin(),image_space_dimensions_3D_.end(),1,std::multiplies()); - - for (size_t i = 0; i < ntimeframes; i++){ - - // Define the image header - // - - GadgetContainerMessage *cm1 = - new GadgetContainerMessage(); - - GadgetContainerMessage< hoNDArray< std::complex > > *cm2 = - new GadgetContainerMessage > >(); - - cm1->getObjectPtr()->flags = 0; - cm1->cont(cm2); - - - cm1->getObjectPtr()->field_of_view[0] = field_of_view_[0]; - cm1->getObjectPtr()->field_of_view[1] = field_of_view_[1]; - cm1->getObjectPtr()->channels = num_coils_; - cm1->getObjectPtr()->repetition = m1->getObjectPtr()->idx.repetition; - - memcpy(cm1->getObjectPtr()->patient_table_position, - m1->getObjectPtr()->patient_table_position, sizeof(float)*3); - - cm1->getObjectPtr()->data_type = ISMRMRD::ISMRMRD_CXFLOAT; - cm1->getObjectPtr()->image_index = 0; - cm1->getObjectPtr()->image_series_index = 0; - - // std::complex and Gadgetron::complext are binary compatible - cuNDArray > cuView(image_space_dimensions_3D_,result->get_data_ptr()+i*nelements3d); - boost::shared_ptr< hoNDArray< complext > > host_result = cuView.to_host(); - *cm2->getObjectPtr() = *((hoNDArray< std::complex >*) host_result.get()); - - cm1->getObjectPtr()->matrix_size[0] = image_space_dimensions_3D_[0]; - cm1->getObjectPtr()->matrix_size[1] = image_space_dimensions_3D_[1]; - cm1->getObjectPtr()->matrix_size[2] = image_space_dimensions_3D_[2]; - cm1->getObjectPtr()->channels = 1; - cm1->getObjectPtr()->image_index = i+1; - - if (this->next()->putq(cm1) < 0) { - GDEBUG("Failed to put result image on to queue\n"); - cm1->release(); - return GADGET_FAIL; - } - } - - num_frames = 0; - } - - } - - m1->release(); - return GADGET_OK; -} - -template GadgetContainerMessage< hoNDArray >* -CMRTGadget::duplicate_array( GadgetContainerMessage< hoNDArray > *array ) -{ - GadgetContainerMessage< hoNDArray > *copy = new GadgetContainerMessage< hoNDArray >(); - *(copy->getObjectPtr()) = *(array->getObjectPtr()); - return copy; -} - -boost::shared_ptr< hoNDArray > -CMRTGadget::extract_samples_from_queue ( std::queue> &queue ) -{ - unsigned int readouts_buffered = queue.size(); - - std::vector dims; - dims.push_back(samples_per_readout_); - dims.push_back(readouts_buffered); - dims.push_back(num_coils_); - - boost::shared_ptr< hoNDArray > host_samples(new hoNDArray(dims)); - - for (unsigned int p=0; p > > *daq = AsContainerMessage > >(mbq); - - if (!daq) { - GDEBUG("Unable to interpret data on message queue\n"); - throw std::runtime_error("CMRTGadget::extract_samples_from_queue: failed to interpret data"); - } - - for (unsigned int c = 0; c < num_coils_; c++) { - - float_complext *data_ptr = host_samples->get_data_ptr(); - data_ptr += c*samples_per_readout_*readouts_buffered+p*samples_per_readout_; - - std::complex *r_ptr = daq->getObjectPtr()->get_data_ptr(); - r_ptr += c*daq->getObjectPtr()->get_size(0); - - memcpy(data_ptr, r_ptr, samples_per_readout_*sizeof(float_complext)); - } - - mbq->release(); - } - - return host_samples; -} - -boost::shared_ptr< hoNDArray > -CMRTGadget::extract_trajectory_from_queue ( std::queue> &queue ) -{ - unsigned int readouts_buffered = queue.size(); - - std::vector dims; - dims.push_back(num_trajectory_dims_); // 2 for trajectories only, 3 for both trajectories + dcw - dims.push_back(samples_per_readout_); - dims.push_back(readouts_buffered); - - boost::shared_ptr< hoNDArray > host_traj(new hoNDArray(dims)); - - for (unsigned int p=0; p > *daq = AsContainerMessage >(mbq); - - if (!daq) { - GDEBUG("Unable to interpret data on message queue\n"); - throw std::runtime_error("CMRTGadget::extract_trajectory_from_queue: failed to interpret data"); - } - - float *data_ptr = host_traj->get_data_ptr(); - data_ptr += num_trajectory_dims_*samples_per_readout_*p; - - float *r_ptr = daq->getObjectPtr()->get_data_ptr(); - - memcpy(data_ptr, r_ptr, num_trajectory_dims_*samples_per_readout_*sizeof(float)); - - mbq->release(); - } - - return host_traj; -} - -void CMRTGadget::extract_trajectory_and_dcw_from_queue -( std::queue> &queue, boost::shared_ptr< hoNDArray > & traj, boost::shared_ptr< hoNDArray > & dcw ) -{ - // Extract trajectory and (if present) density compensation weights. - // They are stored as a float array of dimensions: {2,3} x #samples_per_readout x #readouts. - // We need - // - a floatd2 trajectory array - // - a float dcw array - // - - if( num_trajectory_dims_ == 2 ){ - //This is an evil, evil hack to get the trajectories out. Ohh the horror. - boost::shared_ptr > tmp_traj = extract_trajectory_from_queue( queue ); - std::vector dims_1d; dims_1d.push_back(tmp_traj->get_size(1)*tmp_traj->get_size(2)); - traj = boost::shared_ptr >(new hoNDArray(dims_1d)); - memcpy(traj->get_data_ptr(),tmp_traj->get_data_ptr(),tmp_traj->get_number_of_elements()*sizeof(float)); - - - } - else{ - - boost::shared_ptr< hoNDArray > host_traj_dcw = extract_trajectory_from_queue( queue ); - - std::vector order; - order.push_back(1); order.push_back(2); order.push_back(0); - - auto host_traj_dcw_shifted = permute( *host_traj_dcw, order ); - - std::vector dims_1d; - dims_1d.push_back(host_traj_dcw_shifted.get_size(0)*host_traj_dcw_shifted.get_size(1)); - - dcw = boost::shared_ptr > (new hoNDArray(dims_1d, host_traj_dcw_shifted.get_data_ptr()+2*dims_1d[0])); - - - std::vector dims_2d = dims_1d; dims_2d.push_back(2); - order.clear(); order.push_back(1); order.push_back(0); - - - hoNDArray tmp(dims_2d, host_traj_dcw_shifted.get_data_ptr()); - - auto _traj = permute( tmp, order ); - - traj = boost::shared_ptr > (new hoNDArray(dims_1d, (floatd2*)_traj.get_data_ptr())); - } - - std::vectordims_2d; - dims_2d.push_back(traj->get_number_of_elements()); - dims_2d.push_back(1); // Number of frames - - traj->reshape(dims_2d); - if( num_trajectory_dims_ == 3 ) dcw->reshape(dims_2d); -} - -boost::shared_ptr > CMRTGadget::get_combined_frames(){ - if (frames.size() == 0) - throw std::runtime_error("No frames received. This should not be possible. Your RAM might be replaced with live salmon, or you may have set the expected number of frames to 0"); - - for (unsigned int i = 1; i < frames.size(); i++){ - if (!frames[0]->dimensions_equal(frames[i].get())) - throw std::runtime_error("CMRTGadget: Frames received do not have equal size"); - } - //Get data dimensions. Assume all frames have the same dimensions - std::vector dims = frames[0]->get_dimensions(); - dims.push_back(frames.size()); - - boost::shared_ptr > combined(new cuNDArray(dims)); - - //Copy data into 1 array on device - size_t offset = 0; - for (unsigned int i = 0; i < frames.size(); i++){ - cudaMemcpy(combined->get_data_ptr()+offset,frames[i]->get_data_ptr(),frames[i]->get_number_of_elements()*sizeof(float_complext),cudaMemcpyHostToDevice); - offset += frames[i]->get_number_of_elements(); - } - - frames.clear(); - return combined; -} - -GADGET_FACTORY_DECLARE(CMRTGadget) -} diff --git a/gadgets/hyper/CMRTGadget.h b/gadgets/hyper/CMRTGadget.h deleted file mode 100644 index 0b1ae8588..000000000 --- a/gadgets/hyper/CMRTGadget.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "Gadget.h" -#include "hoNDArray.h" -#include "cuNDArray.h" - -#include "CMRTOperator.h" -#include -#include -#include - -namespace Gadgetron{ - - class CMRTGadget : - public Gadget3< ISMRMRD::AcquisitionHeader, hoNDArray< std::complex >, hoNDArray > - { - - public: - using ReadoutMessage = GadgetContainerMessage>>; - using TrajectoryMessage = GadgetContainerMessage>; - - CMRTGadget(): num_frames(0) { - } - ~CMRTGadget() {} - - protected: - - GADGET_PROPERTY(golden_ratio,bool,"Use golden ratio trajectories",false); - GADGET_PROPERTY(use_TV,bool,"Use total variation",false); - GADGET_PROPERTY(projections_per_recon,int,"Number of projections per reconstruction",0); - GADGET_PROPERTY(iterations,int,"Number of iterations",30); - virtual int process_config(ACE_Message_Block* mb); - - virtual int process(GadgetContainerMessage< ISMRMRD::AcquisitionHeader > *m1, // header - GadgetContainerMessage< hoNDArray< std::complex > > *m2, // data - GadgetContainerMessage< hoNDArray > *m3 ); // traj/dcw - - protected: - - template GadgetContainerMessage< hoNDArray >* - duplicate_array( GadgetContainerMessage< hoNDArray > *array ); - - boost::shared_ptr< hoNDArray > - extract_samples_from_queue ( std::queue> &queue ); - - boost::shared_ptr< hoNDArray > - extract_trajectory_from_queue ( std::queue> &queue ); - - void extract_trajectory_and_dcw_from_queue - ( std::queue> &queue, boost::shared_ptr< hoNDArray > & traj, boost::shared_ptr< hoNDArray > & dcw ); - - /*** - * Combines all stored frames and resets the frame buffer - */ - boost::shared_ptr > get_combined_frames(); - - protected: - - std::vector image_space_dimensions_3D_; - unsigned int projections_per_recon_; - - - std::queue> frame_readout_queue_; - std::queue> frame_traj_queue_; - - std::vector dimensions_; - std::vector field_of_view_; - size_t repetitions_; - size_t samples_per_readout_; - size_t num_coils_; - size_t num_trajectory_dims_; // 2 for trajectories only, 3 for both trajectories + dcw - - std::vector > > frames; - boost::shared_ptr > dcw; - boost::shared_ptr > traj; - unsigned int num_frames; - unsigned int iterations_; - bool golden_ratio_; - bool use_TV_; - }; -} diff --git a/gadgets/hyper/CMakeLists.txt b/gadgets/hyper/CMakeLists.txt deleted file mode 100644 index 509e72271..000000000 --- a/gadgets/hyper/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -add_library(pingvin_hyper SHARED - NFFT2DGadget.h NFFT2DGadget.cpp - CMRT3DGadget.h CMRT3DGadget.cpp - CMRTGadget.h CMRTGadget.cpp - CSIGadget.h CSIGadget.cpp - gpuCSICoilEstimationGadget.cpp - - ) - -set_target_properties(pingvin_hyper PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_hyper - pingvin_core - pingvin_mricore - pingvin_gpuparallelmri - pingvin_toolbox_gpu - pingvin_toolbox_cpucore - pingvin_toolbox_cpufft - pingvin_toolbox_cpucore_math) - - -install(FILES - NFFT2DGadget.h - CMRTGadget.h - CMRT3DGadget.h - CSIGadget.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH}) - -install(FILES NFFT2D.xml CMRT3D.xml CMRT.xml FS-CSI.xml DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH}) - - -install(TARGETS pingvin_hyper - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) \ No newline at end of file diff --git a/gadgets/hyper/CSIGadget.cpp b/gadgets/hyper/CSIGadget.cpp deleted file mode 100644 index d5b211a75..000000000 --- a/gadgets/hyper/CSIGadget.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * CSIGadget.cpp - * - * Created on: Nov 11, 2014 - * Author: dch - */ - -#include "CSIGadget.h" -#include -#include "cudaDeviceManager.h" -#include "cuNDArray_utils.h" -#include "cuNlcgSolver.h" -#include "eigenTester.h" -#include "CSfreqOperator.h" -#include "cuPartialDerivativeOperator.h" -#include "cuDWTOperator.h" -#include -namespace Gadgetron { - -CSIGadget::CSIGadget() { - // TODO Auto-generated constructor stub - -} - -CSIGadget::~CSIGadget() { - // TODO Auto-generated destructor stub -} - - -int CSIGadget::process_config(ACE_Message_Block *mb){ - //GDEBUG("gpuCgSenseGadget::process_config\n"); - - device_number_ = deviceno.value(); - - int number_of_devices = cudaDeviceManager::Instance()->getTotalNumberOfDevice(); - if (number_of_devices == 0) { - GDEBUG( "Error: No available CUDA devices.\n" ); - return GADGET_FAIL; - } - - if (device_number_ >= number_of_devices) { - GDEBUG("Adjusting device number from %d to %d\n", device_number_, (device_number_%number_of_devices)); - device_number_ = (device_number_%number_of_devices); - } - - if (cudaSetDevice(device_number_)!= cudaSuccess) { - GDEBUG( "Error: unable to set CUDA device.\n" ); - return GADGET_FAIL; - } - - cg_limit_ = cg_limit.value(); - oversampling_factor_ = oversampling_factor.value(); - kernel_width_ = kernel_width.value(); - output_convergence_ = output_convergence.value(); - number_of_sb_iterations_ = number_of_sb_iterations.value(); - number_of_cg_iterations_ = number_of_cg_iterations.value(); - - use_compressed_sensing_ = compressed_sensing.value(); - - mu_ = mu.value(); - - // Get the Ismrmrd header - // - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - - - if (h.encoding.size() != 1) { - GDEBUG("This Gadget only supports one encoding space\n"); - return GADGET_FAIL; - } - - // Get the encoding space and trajectory description - ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; - - img_dims_ = {r_space.matrixSize.x,r_space.matrixSize.y,r_space.matrixSize.z}; - - matrix_size_ = vector_td{r_space.matrixSize.x,r_space.matrixSize.y}; - - unsigned int warp_size = cudaDeviceManager::Instance()->warp_size(device_number_); - - matrix_size_os_ = - uint64d2(((static_cast(std::ceil(matrix_size_[0]*oversampling_factor_))+warp_size-1)/warp_size)*warp_size, - ((static_cast(std::ceil(matrix_size_[1]*oversampling_factor_))+warp_size-1)/warp_size)*warp_size); - - - if (h.acquisitionSystemInformation) { - channels_ = h.acquisitionSystemInformation->receiverChannels ? *h.acquisitionSystemInformation->receiverChannels : 1; - } else { - channels_ = 1; - } - - - /*if (~h.userParameters.is_present()){ - GDEBUG("CSI gadget requires userparameters to be set to obtain timesteps."); - return GADGET_FAIL; - }*/ - - - auto parameters = h.userParameters->userParameterDouble; - auto bw = std::find_if(parameters.begin(),parameters.end(), [](ISMRMRD::UserParameterDouble d) { return d.name=="bw";}); - - if (bw->name != "bw"){ - GDEBUG("CSI gadget: User parameter bw is missing."); - return GADGET_FAIL; - } - - - auto dte = std::find_if(parameters.begin(),parameters.end(), [](ISMRMRD::UserParameterDouble d) { return d.name=="dte";}); - if (dte->name != "dte"){ - GDEBUG("CSI gadget: User parameter dte is missing."); - return GADGET_FAIL; - } - -// Allocate encoding operator for non-Cartesian Sense - E_ = boost::make_shared< CSIOperator >(1/bw->value, dte->value); - E_->set_weight(mu_); - - std::vector freqs = frequencies.value(); - - if (freqs.empty()){ - for (float f = frequency_min.value(); f <= frequency_max.value(); f+= frequency_step.value()) - freqs.push_back(f); - } - - - if (freqs.size() == 0) - throw std::runtime_error("CSIGadget: Frequencies not set!"); - - std::stringstream ss; - ss << "Frequencies set: "; - for (auto f : freqs) - ss << f << " "; - GDEBUG(ss.str().c_str()); - - E_->set_frequencies(freqs); - - img_dims_[2]=freqs.size(); - - S_ = boost::make_shared>(); - - E_->set_senseOp(S_); - - - auto idOp = boost::make_shared>>(); - idOp->set_domain_dimensions(img_dims_); - idOp->set_codomain_dimensions(img_dims_); - idOp->set_weight(2*mu_); - solver_.add_regularization_operator(idOp); - - auto dX = boost::make_shared>(0); - dX->set_domain_dimensions(img_dims_); - dX->set_codomain_dimensions(img_dims_); - dX->set_weight(2*mu_); - auto dY = boost::make_shared>(1); - dY->set_domain_dimensions(img_dims_); - dY->set_codomain_dimensions(img_dims_); - dY->set_weight(2*mu_); - auto dZ = boost::make_shared>(2); - dZ->set_domain_dimensions(img_dims_); - dZ->set_codomain_dimensions(img_dims_); - dZ->set_weight(2*mu_); - - - solver_.add_regularization_group_operator(dX); - solver_.add_regularization_group_operator(dY); - - //solver_.add_regularization_group_operator(dZ); - solver_.add_group(); -/* - auto W = boost::make_shared>(); - W->set_domain_dimensions(img_dims_); - W->set_codomain_dimensions(img_dims_); - W->set_weight(2*mu_); - - - auto W2 = boost::make_shared>(); - W2->set_shift(2); - W2->set_domain_dimensions(img_dims_); - W2->set_codomain_dimensions(img_dims_); - W2->set_weight(2*mu_); - solver_.add_regularization_operator(W); - solver_.add_regularization_operator(W2); - */ - // Setup solver - solver_.set_encoding_operator( E_ ); // encoding matrix - solver_.set_max_outer_iterations( number_of_sb_iterations_ ); - solver_.set_max_inner_iterations(1); - solver_.get_inner_solver()->set_max_iterations(number_of_cg_iterations_); - solver_.get_inner_solver()->set_tc_tolerance( cg_limit_ ); - solver_.set_output_mode( (output_convergence_) ? cuCgSolver::OUTPUT_VERBOSE : cuCgSolver::OUTPUT_SILENT); - is_configured_ = true; - return GADGET_OK; - -} - -int CSIGadget::process(GadgetContainerMessage* m1){ - - - if (!is_configured_) { - GDEBUG("\nData received before configuration complete\n"); - return GADGET_FAIL; - } - - - GDEBUG("CSI is on the job\n"); - - - - auto traj = m1->getObjectPtr()->traj; - - auto trajdims2 = std::vector{traj->get_size(0),1}; - //Extract initial trajectory - cuNDArray traj2(trajdims2,traj->get_data_ptr()); - - auto data = m1->getObjectPtr()->data; - auto csm =m1->getObjectPtr()->csm; - auto dcw = m1->getObjectPtr()->dcw; - //dcw.reset(); - - - - - if (dcw) - sqrt_inplace(dcw.get()); - - - E_->set_domain_dimensions(img_dims_); - E_->set_codomain_dimensions(data->get_dimensions()); - - std::vector sense_dims = data->get_dimensions(); - sense_dims[1] = img_dims_[2]; - - - - S_->set_domain_dimensions(img_dims_); - S_->set_codomain_dimensions(sense_dims); - S_->set_csm(csm); - S_->set_dcw(dcw); - S_->setup( matrix_size_, matrix_size_os_, kernel_width_ ); - S_->preprocess(&traj2); - - GDEBUG("Setup done, solving....\n"); - - boost::shared_ptr> result; - if (use_compressed_sensing_) - result = solver_.solve(data.get()); - else { - cgSolver> cgsolver; - cgsolver.set_max_iterations(solver_.get_inner_solver()->get_max_iterations()); - cgsolver.set_encoding_operator(E_); - result = cgsolver.solve(data.get()); - } - - GDEBUG("Image sum: %f \n",asum(result.get())); - m1->release(); - - GDEBUG("Solver done, next patient..."); - - GadgetContainerMessage< hoNDArray< std::complex > > *cm = - new GadgetContainerMessage< hoNDArray< std::complex > >(); - - GadgetContainerMessage *m = - new GadgetContainerMessage(); - - - m->cont(cm); - - - - result->to_host((hoNDArray*)cm->getObjectPtr()); - - GDEBUG("Result size: %i %i %i \n",result->get_size(0),result->get_size(1),result->get_size(2)); - - m->getObjectPtr()->matrix_size[0] = img_dims_[0]; - m->getObjectPtr()->matrix_size[1] = img_dims_[1]; - m->getObjectPtr()->matrix_size[2] = img_dims_[2]; - m->getObjectPtr()->channels = 1; - m->getObjectPtr()->image_index = 1; - m->getObjectPtr()->data_type = ISMRMRD::ISMRMRD_CXFLOAT; - - - if (!this->next()->putq(m)){ - GDEBUG("Failed to put image on que"); - return GADGET_FAIL; - } - - - return GADGET_OK; -} - - GADGET_FACTORY_DECLARE(CSIGadget) - -} /* namespace Gadgetron */ diff --git a/gadgets/hyper/CSIGadget.h b/gadgets/hyper/CSIGadget.h deleted file mode 100644 index 0d7ad7e65..000000000 --- a/gadgets/hyper/CSIGadget.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * CSIGadget.h - * - * Created on: Nov 11, 2014 - * Author: dch - */ - -#ifndef CSIGADGET_H_ -#define CSIGADGET_H_ - -#include "Gadget.h" -#include -#include "GenericReconJob.h" -#include "CSIOperator.h" -#include "cuNonCartesianSenseOperator.h" -#include "cuSbcCgSolver.h" -#include "gpuCSICoilEstimationGadget.h" -namespace Gadgetron { - -class CSIGadget: public Gadgetron::Gadget1{ -public: - CSIGadget(); - virtual ~CSIGadget(); - - virtual int process(GadgetContainerMessage* m1); - virtual int process_config( ACE_Message_Block* mb ); - -protected: - GADGET_PROPERTY(deviceno,int,"GPU device number", 0); - GADGET_PROPERTY(number_of_cg_iterations,int,"Number of CG iterations", 10); - GADGET_PROPERTY(number_of_sb_iterations,int,"Number of SB iterations",20); - GADGET_PROPERTY(cg_limit,float,"CG limit",1e-5f); - GADGET_PROPERTY(oversampling_factor,float,"Oversampling factor",1.5); - GADGET_PROPERTY(kernel_width,float,"Kernel width",5.5); - GADGET_PROPERTY(mu,float,"Mu",1.0); - GADGET_PROPERTY(output_convergence,bool,"Output convergence",false); - GADGET_PROPERTY(frequencies,std::vector,"Frequencies",{}); - GADGET_PROPERTY(frequency_min,float,"Minimum frequency",0); - GADGET_PROPERTY(frequency_max,float,"Maximum frequency",1300); - GADGET_PROPERTY(frequency_step,float,"Frequency step",1300); - GADGET_PROPERTY(compressed_sensing,bool,"Use compressed sensing",true); - - - - int device_number_; - unsigned int number_of_cg_iterations_; - unsigned int number_of_sb_iterations_; - float cg_limit_; - float oversampling_factor_; - float kernel_width_; - float mu_; - float lambda_; - bool output_convergence_; - bool use_compressed_sensing_; - - std::vector img_dims_; - - uint64d2 matrix_size_; - uint64d2 matrix_size_os_; - - boost::shared_ptr > E_; - boost::shared_ptr > S_; - cuSbcCgSolver solver_; - bool is_configured_; - unsigned int channels_; -}; - -} /* namespace Gadgetron */ -#endif /* CSIGADGET_H_ */ diff --git a/gadgets/hyper/FS-CSI.xml b/gadgets/hyper/FS-CSI.xml deleted file mode 100644 index 99cf63818..000000000 --- a/gadgets/hyper/FS-CSI.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - NoiseAdjust - pingvin_mricore - NoiseAdjustGadget - - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out12 - - - - AccumulatorGadget - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionrepetition - - - - BucketToBufferGadget - pingvin_mricore - BucketToBufferGadget - - - CoilEstimation - pingvin_hyper - gpuCSICoilEstimationGadget - kernel_width5.5 - skip_lines1 - - - - CSIGadget - pingvin_hyper - CSIGadget - - frequencies-575.1223 -450.1223 -360.1223 -183.1223 140.8777 - deviceno 0 - number_of_cg_iterations 10 - number_of_sb_iterations 50 - cg_limit 1e-8 - oversampling_factor 2 - kernel_width 7.5 - mu 0.2 - output_convergencetrue - - - - Extract - pingvin_mricore - ExtractGadget - - - - AutoScaleGadget - pingvin_mricore - AutoScaleGadget - - max_value - 512 - - - - diff --git a/gadgets/hyper/NFFT2D.xml b/gadgets/hyper/NFFT2D.xml deleted file mode 100644 index 58561967e..000000000 --- a/gadgets/hyper/NFFT2D.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - NFFT - pingvin_hyper - NFFT2DGadget - - - - Extract - pingvin_mricore - ExtractGadget - - - diff --git a/gadgets/hyper/NFFT2DGadget.cpp b/gadgets/hyper/NFFT2DGadget.cpp deleted file mode 100644 index 55885c2e5..000000000 --- a/gadgets/hyper/NFFT2DGadget.cpp +++ /dev/null @@ -1,334 +0,0 @@ -#include "NFFT2DGadget.h" -#include "cuNFFT.h" -#include "vector_td_utilities.h" -#include "hoNDArray_utils.h" -#include "hoNDArray_fileio.h" -#include "cuNDArray_utils.h" -#include "ismrmrd/xml.h" -#include "radial_utilities.h" -#include - -namespace Gadgetron{ - - int NFFT2DGadget::process_config(ACE_Message_Block* mb) - { - - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - - if (h.encoding.size() != 1) { - GDEBUG("This Gadget only supports one encoding space\n"); - return GADGET_FAIL; - } - - ISMRMRD::EncodingSpace e_space = h.encoding[0].encodedSpace; - ISMRMRD::EncodingSpace r_space = h.encoding[0].reconSpace; - ISMRMRD::EncodingLimits e_limits = h.encoding[0].encodingLimits; - - - GDEBUG("Matrix size: %d, %d\n", e_space.matrixSize.x, e_space.matrixSize.y, e_space.matrixSize.z); - dimensions_.push_back(r_space.matrixSize.x); - dimensions_.push_back(r_space.matrixSize.y); - - field_of_view_.push_back(e_space.fieldOfView_mm.x); - field_of_view_.push_back(e_space.fieldOfView_mm.y); - GDEBUG("FOV: %f, %f\n", r_space.fieldOfView_mm.x, r_space.fieldOfView_mm.y); - - repetitions_ = e_limits.repetition.is_present() ? e_limits.repetition.get().maximum + 1 : 1; - GDEBUG("#Repetitions: %d\n", repetitions_); - - return GADGET_OK; - } - - int NFFT2DGadget::process(GadgetContainerMessage< ISMRMRD::AcquisitionHeader > *m1, // header - GadgetContainerMessage< hoNDArray< std::complex > > *m2, // data - GadgetContainerMessage< hoNDArray > *m3 ) // traj/dcw - { - // Throw away any noise samples if they have been allowed to pass this far down the chain... - // - - bool is_noise = m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT); - if (is_noise) { - m1->release(); - return GADGET_OK; - } - - // First pass initialization - // - - if (frame_readout_queue_.empty()) { - samples_per_readout_ = m1->getObjectPtr()->number_of_samples; - num_coils_ = m1->getObjectPtr()->active_channels; - dimensions_.push_back(m1->getObjectPtr()->active_channels); - dimensions_.push_back(repetitions_); - num_trajectory_dims_ = m3->getObjectPtr()->get_size(0); // 2 for trajectories only, 3 for both trajectories + dcw - } - - int samples = m1->getObjectPtr()->number_of_samples; - int readout = m1->getObjectPtr()->idx.kspace_encode_step_1; - int repetition = m1->getObjectPtr()->idx.kspace_encode_step_2; - - // Enqueue incoming readouts and trajectories - // - - frame_readout_queue_.push(std::unique_ptr(duplicate_array(m2))); - frame_traj_queue_.push(std::unique_ptr(duplicate_array(m3))); - - // If the last readout for a slice has arrived then perform a reconstruction - // - - bool is_last_scan_in_repetition = - m1->getObjectPtr()->isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_REPETITION); - - if (is_last_scan_in_repetition) { - - - // Define the image header - // - - GadgetContainerMessage *cm1 = - new GadgetContainerMessage(); - - GadgetContainerMessage< hoNDArray< std::complex > > *cm2 = - new GadgetContainerMessage > >(); - - cm1->getObjectPtr()->flags = 0; - cm1->cont(cm2); - - cm1->getObjectPtr()->matrix_size[0] = dimensions_[0]; - cm1->getObjectPtr()->matrix_size[1] = dimensions_[1]; - cm1->getObjectPtr()->matrix_size[2] = 1; - cm1->getObjectPtr()->field_of_view[0] = field_of_view_[0]; - cm1->getObjectPtr()->field_of_view[1] = field_of_view_[1]; - cm1->getObjectPtr()->channels = num_coils_; - cm1->getObjectPtr()->repetition = m1->getObjectPtr()->idx.repetition; - - memcpy(cm1->getObjectPtr()->position, - m1->getObjectPtr()->position, - sizeof(float)*3); - - memcpy(cm1->getObjectPtr()->read_dir, - m1->getObjectPtr()->read_dir, - sizeof(float)*3); - - memcpy(cm1->getObjectPtr()->phase_dir, - m1->getObjectPtr()->phase_dir, - sizeof(float)*3); - - memcpy(cm1->getObjectPtr()->slice_dir, - m1->getObjectPtr()->slice_dir, - sizeof(float)*3); - - memcpy(cm1->getObjectPtr()->patient_table_position, - m1->getObjectPtr()->patient_table_position, sizeof(float)*3); - - cm1->getObjectPtr()->data_type = ISMRMRD::ISMRMRD_CXFLOAT; - cm1->getObjectPtr()->image_index = 0; - cm1->getObjectPtr()->image_series_index = 0; - - // - // Perform reconstruction of repetition - // - - // Get samples for frame - // - - cuNDArray samples(*extract_samples_from_queue(frame_readout_queue_)); - - // Get trajectories/dcw for frame - // - - boost::shared_ptr< cuNDArray > traj(new cuNDArray); - boost::shared_ptr > dcw(new cuNDArray); - - extract_trajectory_and_dcw_from_queue(frame_traj_queue_, traj.get(), dcw.get() ); - //traj = compute_radial_trajectory_golden_ratio_2d(samples_per_readout_,dimensions_[1],1,0,GR_ORIGINAL); - - unsigned int num_profiles = samples.get_number_of_elements()/samples_per_readout_; - dcw = compute_radial_dcw_golden_ratio_2d(samples_per_readout_,num_profiles,1.0,1.0f/samples_per_readout_/num_profiles,0,GR_ORIGINAL); - // Create output array - // - - - std::vector img_dims(2); - img_dims[0] = dimensions_[0]; - img_dims[1] = dimensions_[1]; - cm2->getObjectPtr()->create(img_dims); - cuNDArray image(img_dims); - - // Initialize plan - // - - const float kernel_width = 5.5f; - cuNFFT_impl plan( from_std_vector(img_dims), from_std_vector(img_dims)<<1, kernel_width ); - plan.preprocess( *traj, NFFT_prep_mode::NC2C ); -/* - if( dcw->get_number_of_elements() == 0 ){ - std::vector dcw_dims; dcw_dims.push_back(samples_per_readout_); - hoNDArray host_dcw( dcw_dims ); - for( int i=0; i<(int)dcw_dims[0]; i++ ) - host_dcw.get_data_ptr()[i]=abs(i-(int)dcw_dims[0]/2); - host_dcw.get_data_ptr()[dcw_dims[0]/2] = 0.25f; // ad hoc value (we do not want a DC component of 0) - dcw = expand(&host_dcw, traj->get_number_of_elements()/samples_per_readout_); - } -*/ - // Gridder - // - - plan.compute( samples,image, - (dcw->get_number_of_elements()>0) ? dcw.get() : 0x0, - NFFT_comp_mode::BACKWARDS_NC2C ); - - - // Download to host - // - - image.to_host( (hoNDArray*)cm2->getObjectPtr() ); - // Pass on data down the gadget chain - // - - if (this->next()->putq(cm1) < 0) { - return GADGET_FAIL; - } - } - - m1->release(); - return GADGET_OK; - } - - template GadgetContainerMessage< hoNDArray >* - NFFT2DGadget::duplicate_array( GadgetContainerMessage< hoNDArray > *array ) - { - GadgetContainerMessage< hoNDArray > *copy = new GadgetContainerMessage< hoNDArray >(); - *(copy->getObjectPtr()) = *(array->getObjectPtr()); - return copy; - } - - boost::shared_ptr< hoNDArray > - NFFT2DGadget::extract_samples_from_queue (std::queue> &queue) - { - unsigned int readouts_buffered = queue.size(); - - std::vector dims; - dims.push_back(samples_per_readout_*readouts_buffered); - dims.push_back(num_coils_); - - boost::shared_ptr< hoNDArray > host_samples(new hoNDArray(dims)); - - for (unsigned int p=0; p > > *daq = AsContainerMessage > >(mbq); - - if (!daq) { - GDEBUG("Unable to interpret data on message queue\n"); - throw std::runtime_error("NFFT2DGadget::extract_samples_from_queue: failed to interpret data"); - } - - for (unsigned int c = 0; c < num_coils_; c++) { - - float_complext *data_ptr = host_samples->get_data_ptr(); - data_ptr += c*samples_per_readout_*readouts_buffered+p*samples_per_readout_; - - std::complex *r_ptr = daq->getObjectPtr()->get_data_ptr(); - r_ptr += c*daq->getObjectPtr()->get_size(0); - - memcpy(data_ptr, r_ptr, samples_per_readout_*sizeof(float_complext)); - } - - mbq->release(); - } - - return host_samples; - } - - boost::shared_ptr< hoNDArray > - NFFT2DGadget::extract_trajectory_from_queue (std::queue> &queue) - { - unsigned int readouts_buffered = queue.size(); - - std::vector dims; - dims.push_back(num_trajectory_dims_); // 2 for trajectories only, 3 for both trajectories + dcw - dims.push_back(samples_per_readout_); - dims.push_back(readouts_buffered); - - boost::shared_ptr< hoNDArray > host_traj(new hoNDArray(dims)); - - for (unsigned int p=0; p > *daq = AsContainerMessage >(mbq); - - if (!daq) { - GDEBUG("Unable to interpret data on message queue\n"); - throw std::runtime_error("NFFT2DGadget::extract_trajectory_from_queue: failed to interpret data"); - } - - float *data_ptr = host_traj->get_data_ptr(); - data_ptr += num_trajectory_dims_*samples_per_readout_*p; - - float *r_ptr = daq->getObjectPtr()->get_data_ptr(); - - memcpy(data_ptr, r_ptr, num_trajectory_dims_*samples_per_readout_*sizeof(float)); - - mbq->release(); - } - - return host_traj; - } - - void NFFT2DGadget::extract_trajectory_and_dcw_from_queue - ( std::queue> &queue, cuNDArray *traj, cuNDArray *dcw ) - { - // Extract trajectory and (if present) density compensation weights. - // They are stored as a float array of dimensions: {2,3} x #samples_per_readout x #readouts. - // We need - // - a floatd2 trajectory array - // - a float dcw array - // - - if( num_trajectory_dims_ == 2 ){ - boost::shared_ptr< hoNDArray > host_traj = extract_trajectory_from_queue( queue ); - std::vector dims_1d; dims_1d.push_back(host_traj->get_size(1)*host_traj->get_size(2)); - hoNDArray host_traj2(dims_1d,(floatd2*)host_traj->get_data_ptr()); - *traj = cuNDArray(host_traj2); - - } - else{ - - boost::shared_ptr< hoNDArray > host_traj_dcw = extract_trajectory_from_queue( queue ); - - std::vector order; - order.push_back(1); order.push_back(2); order.push_back(0); - - auto host_traj_dcw_shifted = permute( *host_traj_dcw, order ); - - std::vector dims_1d; - dims_1d.push_back(host_traj_dcw_shifted.get_size(0)*host_traj_dcw_shifted.get_size(1)); - - hoNDArray tmp(dims_1d, host_traj_dcw_shifted.get_data_ptr()+2*dims_1d[0]); - *dcw = tmp; - - std::vector dims_2d = dims_1d; dims_2d.push_back(2); - order.clear(); order.push_back(1); order.push_back(0); - - tmp.create(dims_2d, host_traj_dcw_shifted.get_data_ptr()); - auto _traj = permute( tmp, order ); - hoNDArray tmp2(dims_1d,(floatd2*)_traj.get_data_ptr()); - - *traj = cuNDArray(tmp2); - } - - std::vectordims_2d; - dims_2d.push_back(traj->get_number_of_elements()); - dims_2d.push_back(1); // Number of frames - - traj->reshape(dims_2d); - if( num_trajectory_dims_ == 3 ) dcw->reshape(dims_2d); - } - - GADGET_FACTORY_DECLARE(NFFT2DGadget) -} diff --git a/gadgets/hyper/NFFT2DGadget.h b/gadgets/hyper/NFFT2DGadget.h deleted file mode 100644 index 25ba808cc..000000000 --- a/gadgets/hyper/NFFT2DGadget.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "Gadget.h" -#include "hoNDArray.h" -#include "cuNDArray.h" - -#include -#include -#include - -namespace Gadgetron{ - - class NFFT2DGadget : - public Gadget3< ISMRMRD::AcquisitionHeader, hoNDArray< std::complex >, hoNDArray > - { - - public: - using ReadoutMessage = GadgetContainerMessage>>; - using TrajectoryMessage = GadgetContainerMessage>; - - NFFT2DGadget() {} - ~NFFT2DGadget() {} - - protected: - - virtual int process_config(ACE_Message_Block* mb); - - virtual int process(GadgetContainerMessage< ISMRMRD::AcquisitionHeader > *m1, // header - GadgetContainerMessage< hoNDArray< std::complex > > *m2, // data - GadgetContainerMessage< hoNDArray > *m3 ); // traj/dcw - - protected: - - template GadgetContainerMessage< hoNDArray >* - duplicate_array( GadgetContainerMessage< hoNDArray > *array ); - - boost::shared_ptr< hoNDArray > - extract_samples_from_queue ( std::queue> &queue); - - boost::shared_ptr< hoNDArray > - extract_trajectory_from_queue ( std::queue> &queue ); - - void extract_trajectory_and_dcw_from_queue - ( std::queue> &queue, cuNDArray *traj, cuNDArray *dcw ); - - protected: - std::queue> frame_readout_queue_; - std::queue> frame_traj_queue_; - std::vector dimensions_; - std::vector field_of_view_; - size_t repetitions_; - size_t samples_per_readout_; - size_t num_coils_; - size_t num_trajectory_dims_; // 2 for trajectories only, 3 for both trajectories + dcw - }; -} diff --git a/gadgets/hyper/gpuCSICoilEstimationGadget.cpp b/gadgets/hyper/gpuCSICoilEstimationGadget.cpp deleted file mode 100644 index 02b981d0c..000000000 --- a/gadgets/hyper/gpuCSICoilEstimationGadget.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * gpuCSICoilEstimationGadget.cpp - * - * Created on: Nov 12, 2014 - * Author: dch - */ - -#include "gpuCSICoilEstimationGadget.h" -#include -#include -#include "cuNDArray.h" -#include "cuNFFT.h" -#include "b1_map.h" -#include "vector_td_utilities.h" -#include "../../toolboxes/nfft/NFFTOperator.h" -#include "cuCgSolver.h" -#include "cuNDArray_fileio.h" -#include "trajectory_utils.h" -#include -#include "hoNDArray_math.h" - -namespace Gadgetron { - -gpuCSICoilEstimationGadget::gpuCSICoilEstimationGadget() { - -} - -gpuCSICoilEstimationGadget::~gpuCSICoilEstimationGadget() { - // TODO Auto-generated destructor stub -} - -int gpuCSICoilEstimationGadget::process_config(ACE_Message_Block* mb) { - ISMRMRD::IsmrmrdHeader h; - ISMRMRD::deserialize(mb->rd_ptr(),h); - - if (h.encoding.size() != 1){ - GDEBUG("Coil estimation gadget only supports encoding spaces of size 1\n"); - return GADGET_FAIL; - } - img_size = {h.encoding[0].reconSpace.matrixSize.x,h.encoding[0].reconSpace.matrixSize.y}; - kernel_width_ = kernel_width.value(); - - coils = h.acquisitionSystemInformation->receiverChannels; - skip_lines_ = skip_lines.value(); - return GADGET_OK; -} - -int gpuCSICoilEstimationGadget::process( - GadgetContainerMessage* m1) { - IsmrmrdReconData* bucket = m1->getObjectPtr(); - - auto cm1 = new GadgetContainerMessage(); - auto senseData = cm1->getObjectPtr(); - - coils = bucket->rbit_.front().data_.headers_[0].active_channels; - GDEBUG("Active channels %i \n",coils); - - - { - - hoNDArray> * ho_data = &bucket->rbit_.front().data_.data_; - hoNDArray* ho_traj = &bucket->rbit_.front().data_.trajectory_.value(); - - - if (skip_lines_ > 0){ - - - - auto separated = split_calibration_lines>(*ho_data,skip_lines_,1); - - senseData->freq_calibration = boost::make_shared>((hoNDArray&)(*std::get<0>(separated).get())); - senseData->freq_calibration->squeeze(); - senseData->data = boost::make_shared>((hoNDArray&)(*std::get<1>(separated).get())); - } else { - - senseData->data = boost::make_shared>(reinterpret_cast&>(*ho_data)); - } - - - if (ho_traj->get_size(0) > 2){ //We have dcw - auto traj_dcw = separate_traj_and_dcw(ho_traj); - senseData->traj = boost::make_shared>(*std::get<0>(traj_dcw)); - senseData->dcw = boost::make_shared>(*std::get<1>(traj_dcw)); - } else { - std::vector tdims = ho_traj->get_dimensions(); - std::vector tmp_dim(tdims.begin()+1,tdims.end()); - hoNDArray tmp(tmp_dim,reinterpret_cast(ho_traj->get_data_ptr())); - senseData->traj = boost::make_shared>(tmp); - } - - } - - - //Remove Initial Spirals - - boost::shared_ptr< cuNDArray > ref_data; - boost::shared_ptr< cuNDArray > ref_traj; - boost::shared_ptr > ref_dcw; - - - - if (!bucket->rbit_.front().ref_){ - GDEBUG("Setting reference data to real data\n"); - ref_data = senseData->data; - ref_traj = senseData->traj; - ref_dcw = senseData->dcw; - } else { - - auto & ref = *bucket->rbit_.front().ref_; - - hoNDArray> * ho_data = &ref.data_; - hoNDArray* ho_traj = &ref.trajectory_.value(); - - ref_data = boost::make_shared>(reinterpret_cast&>(*ho_data)); - if (ho_traj->get_size(0) > 2){ - auto traj_dcw = separate_traj_and_dcw(ho_traj); - ref_traj =boost::make_shared>(*std::get<0>(traj_dcw)); - ref_dcw = boost::make_shared>(*std::get<1>(traj_dcw)); - } else { - std::vector tdims = ho_traj->get_dimensions(); - std::vector tmp_dim(tdims.begin()+1,tdims.end()); - hoNDArray tmp(tmp_dim,reinterpret_cast(ho_traj->get_data_ptr())); - ref_traj = boost::make_shared>(tmp); - } - } - - - senseData->csm = calculate_CSM(ref_data.get(),ref_traj.get(),ref_dcw.get()); - - - - if (this->next()->putq(cm1) == GADGET_FAIL){ - GERROR("Failed to put message on que\n"); - return GADGET_FAIL; - } - - return GADGET_OK; - - -} - - -boost::shared_ptr > gpuCSICoilEstimationGadget::calculate_CSM( - cuNDArray* data, cuNDArray* traj, cuNDArray* dcw ) { - - std::vector csm_dims = img_size; - csm_dims.push_back(coils); - std::vector flat_dims = {traj->get_number_of_elements()}; - cuNDArray flat_traj(flat_dims,traj->get_data_ptr()); - std::vector spiral_dims{data->get_size(0)*data->get_size(1)*data->get_size(2),data->get_size(3)}; //Trajectories, coils - cuNDArray> second_spiral(spiral_dims,data->get_data_ptr()); - std::vector spiral_traj_dims{spiral_dims[0]}; - cuNDArray spiral_traj(spiral_traj_dims,traj->get_data_ptr()); - if (dcw) { //We have density compensation, so we can get away with gridding - - cuNFFT_impl plan(from_std_vector(img_size),from_std_vector(img_size)*size_t(2),kernel_width_); - cuNDArray tmp(csm_dims); - GDEBUG("Coils %i \n\n",tmp.get_size(2)); - - cuNDArray spiral_dcw(spiral_traj_dims,dcw->get_data_ptr()); - - GDEBUG("Preprocessing\n\n"); - plan.preprocess(spiral_traj,NFFT_prep_mode::NC2C); - GDEBUG("Computing\n\n"); - - auto tmp_abs = abs(&tmp); - - return boost::make_shared>(estimate_b1_map(tmp)); - - } else { //No density compensation, we have to do iterative reconstruction. - - - auto E = boost::make_shared>(); - - E->setup(from_std_vector(img_size),from_std_vector(img_size)*size_t(2),kernel_width_); - - E->set_codomain_dimensions(spiral_dims); - E->set_domain_dimensions(csm_dims); - cuCgSolver solver; - solver.set_max_iterations(20); - solver.set_encoding_operator(E); - - E->preprocess(spiral_traj); - - auto tmp = solver.solve(&second_spiral); - auto tmp_abs = abs(tmp.get()); - - - - auto res = estimate_b1_map(*tmp); - //fill(res.get(),float_complext(1,0)); - //auto res= boost::make_shared>(csm_dims); - //fill(res.get(),float_complext(1,0)); - return boost::make_shared>(res); - - } - -} - -std::tuple >, boost::shared_ptr>> gpuCSICoilEstimationGadget::separate_traj_and_dcw( - hoNDArray* traj_dcw) { - std::vector dims = traj_dcw->get_dimensions(); - std::vector reduced_dims(dims.begin()+1,dims.end()); //Copy vector, but leave out first dim - auto dcw = boost::make_shared>(reduced_dims); - - auto traj = boost::make_shared>(reduced_dims); - - auto dcw_ptr = dcw->get_data_ptr(); - auto traj_ptr = traj->get_data_ptr(); - auto ptr = traj_dcw->get_data_ptr(); - - for (size_t i = 0; i < traj_dcw->get_number_of_elements()/3; i++){ - traj_ptr[i][0] = ptr[i*3]; - traj_ptr[i][1] = ptr[i*3+1]; - dcw_ptr[i] = ptr[i*3+2]; - } - - return std::make_tuple(traj,dcw); - - -} - - -template std::tuple>, boost::shared_ptr> > gpuCSICoilEstimationGadget::split_calibration_lines(hoNDArray& data, int ncal_lines, int dim){ - - auto dimensions = data.get_dimensions(); - - size_t cal_dim = dimensions[dim]; - if (ncal_lines >= dimensions[dim]){ - throw std::runtime_error("Number of calibration lines is longer or equal to data size. No data left for reconstruction!"); - } - auto cal_dims = dimensions; - cal_dims[dim] = ncal_lines; - dimensions[dim] -= ncal_lines; - - auto calibration_data = boost::make_shared>(cal_dims); - auto recon_data = boost::make_shared>(dimensions); - - size_t smaller_dims = 1; - for (auto i = 0u; i < dim;i++) - smaller_dims *= dimensions[i]; - - size_t larger_dims = 1; - for (auto i = dim+1; i < dimensions.size(); i++) - larger_dims *= dimensions[i]; - - - auto cal_ptr = calibration_data->get_data_ptr(); - auto recon_ptr = recon_data->get_data_ptr(); - auto data_ptr = data.get_data_ptr(); - - for (auto k = 0u; k < larger_dims; k++){ - for (auto n = 0u; n < ncal_lines; n++){ - for (auto m = 0u; m < smaller_dims; m++){ - cal_ptr[m+n*smaller_dims+k*ncal_lines*smaller_dims] = data_ptr[m+n*smaller_dims+k*smaller_dims*cal_dim]; - } - } - for (auto n = 0u; n < dimensions[dim]; n++){ - for (auto m = 0u; m < smaller_dims; m++){ - recon_ptr[m+n*smaller_dims+k*dimensions[dim]*smaller_dims] = data_ptr[m+(n+ncal_lines)*smaller_dims+k*smaller_dims*cal_dim]; - } - } - } - - - return std::make_tuple(calibration_data,recon_data); - - - - -} - - -GADGET_FACTORY_DECLARE(gpuCSICoilEstimationGadget) - -} /* namespace Gadgetron */ diff --git a/gadgets/hyper/gpuCSICoilEstimationGadget.h b/gadgets/hyper/gpuCSICoilEstimationGadget.h deleted file mode 100644 index 2292c1797..000000000 --- a/gadgets/hyper/gpuCSICoilEstimationGadget.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * gpuCSICoilEstimationGadget.h - * - * Created on: Nov 12, 2014 - * Author: dch - */ - -#ifndef gpuCSICoilESTIMATIONGADGET_H_ -#define gpuCSICoilESTIMATIONGADGET_H_ - -#include "Gadget.h" -#include -#include "cuNDArray.h" - -namespace Gadgetron { - -class gpuCSICoilEstimationGadget: public Gadgetron::Gadget1 { -public: - gpuCSICoilEstimationGadget(); - virtual ~gpuCSICoilEstimationGadget(); - virtual int process_config(ACE_Message_Block* mb); - - virtual int process(GadgetContainerMessage* m1); - -protected: - - template std::tuple>, boost::shared_ptr>> split_calibration_lines(hoNDArray& data, int calibration_lines, int dim); - boost::shared_ptr> calculate_CSM(cuNDArray* data,cuNDArray* traj, cuNDArray* dcw ); -/** - * Separates trajectory and dcw - * @param array containing trajectory and dcw, so that the first dimension has size 3 - * @return tuple containing trajectory and dcw - */ - static std::tuple >, boost::shared_ptr>> separate_traj_and_dcw(hoNDArray*); - std::vector img_size; - size_t coils; - - - GADGET_PROPERTY(kernel_width,float,"Kernel width for NFFT calculation",5.5); - GADGET_PROPERTY(skip_lines,unsigned int,"Calibration lines to skip",0); - - float kernel_width_; - - unsigned int skip_lines_; - -}; - - -struct cuSenseData { - boost::shared_ptr> data; - boost::shared_ptr> traj; - boost::shared_ptr> csm; - boost::shared_ptr> dcw; - boost::shared_ptr> freq_calibration; - -}; - -} /* namespace Gadgetron */ -#endif /* gpuCSICoilESTIMATIONGADGET_H_ */ diff --git a/gadgets/moco/CMakeLists.txt b/gadgets/moco/CMakeLists.txt deleted file mode 100644 index bb6f1c3cc..000000000 --- a/gadgets/moco/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -if (CUDA_FOUND) - list(APPEND CPU_GADGETS cpuRegistrationAveragingGadget.cpp) - list(APPEND CPU_LIBS pingvin_toolbox_cpucore_math pingvin_toolbox_cpureg) - - - list(APPEND GPU_GADGETS gpuRegistrationAveragingGadget.cpp gpuRegistrationScatteringGadget.cpp) - list(APPEND GPU_LIBS pingvin_toolbox_gpu ${CUDA_LIBRARIES}) - - - add_library(pingvin_moco SHARED - cpuRegistrationAveragingGadget.h - gpuRegistrationAveragingGadget.h - gpuRegistrationScatteringGadget.h - RegistrationAveragingGadget.h - RegistrationScatteringGadget.h - ${CPU_GADGETS} - ${GPU_GADGETS} - ) - - set_target_properties(pingvin_moco PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - - target_link_libraries(pingvin_moco - pingvin_core - pingvin_toolbox_cpucore pingvin_mricore - pingvin_toolbox_gpu - ) - - install(TARGETS pingvin_moco - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - install(TARGETS pingvin_moco DESTINATION lib COMPONENT main) - - install(FILES cpuRegistrationAveragingGadget.h - gpuRegistrationAveragingGadget.h - gpuRegistrationScatteringGadget.h - RegistrationAveragingGadget.h - RegistrationScatteringGadget.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - - add_subdirectory(config) -elseif (CUDA_FOUND) - message("Cuda not found, not compiling gpu-based registration gadgets") -endif () \ No newline at end of file diff --git a/gadgets/moco/RegistrationAveragingGadget.h b/gadgets/moco/RegistrationAveragingGadget.h deleted file mode 100644 index 738e95c3e..000000000 --- a/gadgets/moco/RegistrationAveragingGadget.h +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef RegistrationAveragingGadget_H -#define RegistrationAveragingGadget_H - -#include "Gadget.h" -#include "hoNDArray.h" -#include "complext.h" -#include "PhysioInterpolationGadget.h" -#include "GadgetronTimer.h" -#include "hoNDArray_fileio.h" - -#ifdef USE_CUDA -#include "cuNDArray_reductions.h" -#endif // USE_CUDA - -#include -#include - -#include - -namespace Gadgetron{ - - template class opticalFlowSolver; - - /** - This is an abstract gadget class and consequently should not be included in any xml configuration file. - "Instantiate" instead the cpuRegistrationAveragingGadget or gpuRegistrationAveragingGadget. - */ - template class RegistrationAveragingGadget - : public Gadget2 > // se note below - { - // - // We use hoNDArray to interface the gadget chain, even if ARRAY_TYPE is a cuNDArray - // Instead of hard coding the interface to use single precision (float), - // "typename ARRAY_TYPE::element_type" could in principle denote a double precision type (double) as well. - // Registration of complex images is however not supported currently... - // - - public: - - RegistrationAveragingGadget() { - this->of_solver_ = 0x0; - this->number_of_phases_ = 0; // This is a property queried from the PhysioInterpolationGadget - } - - virtual ~RegistrationAveragingGadget() { - if( this->of_solver_ ) delete this->of_solver_; - } - - protected: - GADGET_PROPERTY(alpha, float, "Alpha regularization parameters", 0.05); - GADGET_PROPERTY(beta, float, "Beta regularization parameters", 1.0); - GADGET_PROPERTY(limit, float, "Iteration limit", 0.01); - GADGET_PROPERTY(num_multiresolution_levels, int, "Number of multiresolution levels", 3); - GADGET_PROPERTY(max_iterations_per_level, int, "Maximum number of iterations per level", 500); - GADGET_PROPERTY(output_convergence, bool, "Output convergence", false); - GADGET_PROPERTY(phases, unsigned short, "Number of cardiac phases", 30); - - - virtual int process_config(ACE_Message_Block *mb) - { - this->alpha_ = (typename ARRAY_TYPE::element_type)alpha.value(); - this->beta_ = (typename ARRAY_TYPE::element_type)beta.value(); - this->limit_ = (typename ARRAY_TYPE::element_type)limit.value(); - this->output_convergence_ = output_convergence.value(); - this->num_multires_levels_ = num_multiresolution_levels.value(); - this->max_iterations_per_level_ = max_iterations_per_level.value(); - - this->number_of_phases_ = phases.value(); - - GDEBUG("Configured for %d phases\n", this->number_of_phases_); - return GADGET_OK; - } - - virtual int process( GadgetContainerMessage< ISMRMRD::ImageHeader > *m1, - GadgetContainerMessage< hoNDArray< typename ARRAY_TYPE::element_type > > *m2 ) - { - - //GDEBUG("\nSERIES: %d, PHASE: %d", m1->getObjectPtr()->image_series_index, m1->getObjectPtr()->phase ); - - // If this image header corresponds to series 0, it is not part of the sorted phases. - // Just pass those images along... - // - - if( m1->getObjectPtr()->image_series_index < 9 ){ - return this->next()->putq(m1); - } - - // At first pass allocate the image buffer array. - // - - if( this->phase_images_.empty() ){ - - this->image_dimensions_ = m2->getObjectPtr()->get_dimensions(); - this->phase_images_ = decltype(this->phase_images_){}; - - size_t bsize = sizeof(GadgetContainerMessage)*100*this->number_of_phases_; - - - // Setup the optical flow solver - // - - if( this->setup_solver() != GADGET_OK ){ - GDEBUG("Failed to set up optical flow solver\n"); - return GADGET_FAIL; - } - } - - // - // Put the incoming images on the appropriate queue (based on the phase index). - // - unsigned int phase = m1->getObjectPtr()->phase; - - this->phase_images_[phase].emplace(m1); - - return GADGET_OK; - } - - // All the work is done here in the close method - // - - virtual int close(unsigned long flags) - { - if( !this->phase_images_.empty()){ - - GDEBUG("RegistrationAveragingGadget::close (performing registration and averaging images)\n"); - - // Make sure we have the same number of images on all phase queues - // (It doesn't really matter, but if not the case something probably went wrong upstream) - // - - unsigned int num_images = this->phase_images_[0].size(); - - GDEBUG("Number of images for phase 0: %d", num_images ); - - for( unsigned int phase = 0; phase< this->number_of_phases_; phase++ ){ - - unsigned int num_images_phase = this->phase_images_[phase].size(); - GDEBUG("Number of images for phase %d: %d", phase, num_images_phase ); - - if( num_images != num_images_phase ){ - GDEBUG("Failed to set up registration, a different number of images received for each phase\n"); - return Gadget::close(flags); - } - } - - if( num_images == 0 ){ - GDEBUG("No images to register\n"); - return Gadget::close(flags); - } - - for( unsigned int phase=0; phase < this->number_of_phases_; phase++ ){ - - unsigned int num_image_elements = this->image_dimensions_[0]*image_dimensions_[1]; - std::vector moving_dims = this->image_dimensions_; - moving_dims.push_back(num_images-1); - - GadgetContainerMessage *header; - - ARRAY_TYPE fixed_image; - ARRAY_TYPE moving_image(moving_dims); - - for( unsigned int image=0; imagephase_images_[phase].front().release(); - - this->phase_images_[phase].pop(); - - GadgetContainerMessage< hoNDArray > *m2 = - AsContainerMessage< hoNDArray >(m1->cont()); - - if( m2 == 0x0 ) { - GDEBUG("Unexpected continuation on queue\n"); - m1->release(); - return Gadget::close(flags); - } - - if( image == 0 ){ - - // Setup the fixed image. - // If ARRAY_TYPE is an cuNDArray the following assignment uploads the array to the device, - // for an 'hoNDArray' it merely copies the array. - fixed_image = *m2->getObjectPtr(); - - // We are going to pass on the averaged image using this header - header = m1; - - // The continuation will be a new array (set after registration). - // No registration is however performed if we received only one image. - // In the latter case keep the current continuation. - if( num_images > 1 ){ - m1->cont(0x0); - m2->release(); - } - } - else{ - - // Assign this image as the 'image-1'th frame in the moving image - ARRAY_TYPE tmp_moving(image_dimensions_, moving_image.get_data_ptr()+(image-1)*num_image_elements); - tmp_moving = *m2->getObjectPtr(); // Copy as for the fixed image - m1->release(); - } - } - - if( num_images > 1 ){ - - // Perform registration for the current phase - // - - boost::shared_ptr deformations; - { - GadgetronTimer timer("Running registration"); - deformations = this->of_solver_->solve( &fixed_image, &moving_image ); - } - - // Deform moving images based on the registration - // - - boost::shared_ptr deformed_moving; - { - GadgetronTimer timer("Applying deformation"); - deformed_moving = this->of_solver_->deform( &moving_image, deformations ); - } - - // Accumulate the deformed moving images (into one image) and add this image to the fixed image. - // Then divide by the number of images to get the average. - // - - fixed_image += ((deformed_moving->get_number_of_dimensions() == 3) ? *sum(deformed_moving.get(), 2) : *deformed_moving); - fixed_image /= ((typename ARRAY_TYPE::element_type)num_images); - - // Pass along averaged image - // - - if( set_continuation( header, &fixed_image ) < 0 ) { - GDEBUG("Failed to set continuation\n"); - header->release(); - return Gadget::close(flags); - } - } - - if( this->next()->putq(header) < 0 ) { - GDEBUG("Failed to put registrered image on queue\n"); - header->release(); - return Gadget::close(flags); - } - } - } - - return Gadget::close(flags); - } - - virtual int setup_solver() = 0; - virtual int set_continuation( GadgetContainerMessage* m1, ARRAY_TYPE *continuation ) = 0; - - protected: - opticalFlowSolver *of_solver_; - typename ARRAY_TYPE::element_type alpha_; - typename ARRAY_TYPE::element_type beta_; - typename ARRAY_TYPE::element_type limit_; - bool output_convergence_; - unsigned int num_multires_levels_; - unsigned int max_iterations_per_level_; - - private: - std::map>>> phase_images_; - std::vector image_dimensions_; - unsigned short number_of_phases_; - }; -} - -#endif //RegistrationAveragingGadget_H diff --git a/gadgets/moco/RegistrationScatteringGadget.h b/gadgets/moco/RegistrationScatteringGadget.h deleted file mode 100644 index e4d5f3baf..000000000 --- a/gadgets/moco/RegistrationScatteringGadget.h +++ /dev/null @@ -1,316 +0,0 @@ -#ifndef RegistrationScatteringGadget_H -#define RegistrationScatteringGadget_H - -#include "Gadget.h" -#include "hoNDArray.h" -#include "complext.h" -#include "PhysioInterpolationGadget.h" -#include "GadgetronTimer.h" -#include "hoNDArray_fileio.h" - -#include -#include -#include - -namespace Gadgetron{ - - template class opticalFlowSolver; - - /** - This is an abstract gadget class and consequently should not be included in any xml configuration file. - Use instead the gpuRegistrationScatteringGadget. - */ - template class RegistrationScatteringGadget - : public Gadget2 > // se note below - { - // - // We use hoNDArray to interface the gadget chain, even if ARRAY_TYPE is a cuNDArray - // Instead of hard coding the interface to use single precision (float), - // "typename ARRAY_TYPE::element_type" could in principle denote a double precision type (double) as well. - // Registration of complex images is however not supported currently. - // - - public: - - RegistrationScatteringGadget() { - this->of_solver_ = 0x0; - this->number_of_phases_ = 0; // This is a property queried from the PhysioInterpolationGadget - } - - virtual ~RegistrationScatteringGadget() { - if( this->of_solver_ ) delete this->of_solver_; - } - - protected: - GADGET_PROPERTY(alpha, float, "Alpha regularization parameters", 0.05); - GADGET_PROPERTY(beta, float, "Beta regularization parameters", 1.0); - GADGET_PROPERTY(limit, float, "Iteration limit", 0.01); - GADGET_PROPERTY(num_multiresolution_levels, int, "Number of multiresolution levels", 3); - GADGET_PROPERTY(max_iterations_per_level, int, "Maximum number of iterations per level", 500); - GADGET_PROPERTY(output_convergence, bool, "Output convergence", false); - GADGET_PROPERTY(phases, unsigned short, "Number of cardiac phases", 30); - - virtual int process_config(ACE_Message_Block *mb) - { - this->alpha_ = (typename ARRAY_TYPE::element_type)alpha.value(); - this->beta_ = (typename ARRAY_TYPE::element_type)beta.value(); - this->limit_ = (typename ARRAY_TYPE::element_type)limit.value(); - this->output_convergence_ = output_convergence.value(); - this->num_multires_levels_ = num_multiresolution_levels.value(); - this->max_iterations_per_level_ = max_iterations_per_level.value(); - - this->number_of_phases_ = phases.value(); - - GDEBUG("Configured for %d phases\n", this->number_of_phases_); - return GADGET_OK; - } - - virtual int process( GadgetContainerMessage< ISMRMRD::ImageHeader > *m1, - GadgetContainerMessage< hoNDArray< typename ARRAY_TYPE::element_type > > *m2 ) - { - - //GDEBUG("\nSERIES: %d, PHASE: %d", m1->getObjectPtr()->image_series_index, m1->getObjectPtr()->phase ); - - // If this image header corresponds to series 0, it is not part of the sorted phases. - // Just pass those images along... - // - - if( m1->getObjectPtr()->image_series_index < 9 ){ - return this->next()->putq(m1); - } - - // At first pass allocate the image buffer array. - // - - if( this->image_dimensions_.empty() ){ - - this->image_dimensions_ = m2->getObjectPtr()->get_dimensions(); - this->phase_images_ = decltype(this->phase_images_){}; - - - // Setup the optical flow solver - // - - if( this->setup_solver() != GADGET_OK ){ - GDEBUG("Failed to set up optical flow solver\n"); - return GADGET_FAIL; - } - } - - // - // Put the incoming images on the appropriate queue (based on the phase index). - // - - unsigned int phase = m1->getObjectPtr()->phase; - this->phase_images_[phase].emplace(m1); - - return GADGET_OK; - } - - // All the work is done here in the close method - // - virtual int close(unsigned long flags) - { - if( !this->phase_images_.empty() ){ - - GDEBUG("RegistrationScatteringGadget::close (performing registration and scattering images)\n"); - - // Make sure we have the same number of images on all phase queues - // (It doesn't really matter, but if not the case something probably went wrong upstream) - // - - unsigned int num_images = this->phase_images_[0].size(); - - GDEBUG("Number of images for phase 0: %d", num_images ); - - for( unsigned int phase = 0; phase< this->number_of_phases_; phase++ ){ - - unsigned int num_images_phase = this->phase_images_[phase].size(); - GDEBUG("Number of images for phase %d: %d", phase, num_images_phase ); - - if( num_images != num_images_phase ){ - GDEBUG("Failed to set up registration, a different number of images received for each phase\n"); - return Gadget::close(flags); - } - } - - if( num_images == 0 ){ - GDEBUG("No images to register\n"); - return Gadget::close(flags); - } - - // These are the dimensions of the vector field written out - // - just a plain 'write_nd_array' below for now... - // - - std::vector reg_dims = this->image_dimensions_; // x,y - reg_dims.push_back(num_images-1); // this many registrations - reg_dims.push_back(2); // 2d flow vectors - reg_dims.push_back(this->number_of_phases_); - ARRAY_TYPE reg_field(reg_dims); - unsigned int num_reg_elements_phase = reg_dims[0]*reg_dims[1]*reg_dims[2]*reg_dims[3]; - - for( unsigned int phase=0; phase < this->number_of_phases_; phase++ ){ - - unsigned int num_image_elements = this->image_dimensions_[0]*image_dimensions_[1]; - std::vector fixed_dims = this->image_dimensions_; - fixed_dims.push_back(num_images-1); - - std::vector< GadgetContainerMessage*> headers; - - ARRAY_TYPE fixed_image(fixed_dims); - ARRAY_TYPE moving_image; - - for( unsigned int image=0; imagephase_images_[phase].front().release(); - this->phase_images_[phase].pop(); - - GadgetContainerMessage< hoNDArray > *m2 = - AsContainerMessage< hoNDArray >(m1->cont()); - - if( m2 == 0x0 ) { - GDEBUG("Unexpected continuation on queue\n"); - m1->release(); - return Gadget::close(flags); - } - - if( image == 0 ){ - - // Setup the moving image. - // If ARRAY_TYPE is an cuNDArray the following assignment uploads the array to the device, - // for an 'hoNDArray' it merely copies the array. - // - - moving_image = *m2->getObjectPtr(); - headers.push_back(m1); - } - else{ - - // Assign this image as the 'image-1'th frame in the moving image - // - - ARRAY_TYPE tmp_fixed(image_dimensions_, fixed_image.get_data_ptr()+(image-1)*num_image_elements); - tmp_fixed = *m2->getObjectPtr(); // Copy as for the moving image - headers.push_back(m1); - - // The continuation will be a new array (set after registration). - // No registration is however performed if we received only one image. - // In the latter case keep the current continuation. - // - - if( num_images > 1 ){ - m1->cont(0x0); - m2->release(); - } - } - } - - if( num_images > 1 ){ - - // Perform registration for the current phase - // - - boost::shared_ptr deformations; - { - GadgetronTimer timer("Running registration"); - deformations = this->of_solver_->solve( &fixed_image, &moving_image ); - } - - // Copy displacement field to vector field array - // - - { - std::vector phase_reg_dims = reg_dims; phase_reg_dims.pop_back(); - ARRAY_TYPE tmp_in(phase_reg_dims, deformations->get_data_ptr() ); // the vector field has an extra dimension for CK (to be discarded) - ARRAY_TYPE tmp_out(phase_reg_dims, reg_field.get_data_ptr()+phase*num_reg_elements_phase ); - tmp_out = tmp_in; - } - - // Deform moving images based on the registration - // - - boost::shared_ptr deformed_moving; - { - GadgetronTimer timer("Applying deformation"); - deformed_moving = this->of_solver_->deform( &moving_image, deformations ); - } - - // Pass along the deformed moving images - // - - for( unsigned int i=0; inext()->putq(headers[i]) < 0 ) { - GDEBUG("Failed to put registrered image on queue\n"); - headers[i]->release(); - return Gadget::close(flags); - } - } - else{ - std::vector moving_dims = moving_image.get_dimensions(); - cuNDArray subimage( moving_dims, deformed_moving->get_data_ptr()+(i-1)*num_image_elements); - - if( set_continuation( headers[i], &subimage ) < 0 ) { - GDEBUG("Failed to set continuation\n"); - headers[i]->release(); - return Gadget::close(flags); - } - - GDEBUG("Putting image %d image on queue\n", i); - - if( this->next()->putq(headers[i]) < 0 ) { - GDEBUG("Failed to put registrered image on queue\n"); - headers[i]->release(); - return Gadget::close(flags); - } - } - } - } - } - - // Write out the result after permutation to the data order - // - to be betetr suited for a subsequent reconstruction pass - // - - std::vector order; - order.push_back(0); - order.push_back(1); - order.push_back(4); - order.push_back(2); - order.push_back(3); - - GDEBUG("Writing out displacement field with dimensions: %d %d %d %d %d\n", order[0], order[1], order[2], order[3], order[4]); - auto displacement_field = permute(reg_field,order); - write_displacement_field( &displacement_field ); - - } - - return Gadget::close(flags); - } - - virtual int setup_solver() = 0; - virtual int set_continuation( GadgetContainerMessage* m1, ARRAY_TYPE *continuation ) = 0; - virtual int write_displacement_field( ARRAY_TYPE *vec_field ) = 0; - - protected: - opticalFlowSolver *of_solver_; - typename ARRAY_TYPE::element_type alpha_; - typename ARRAY_TYPE::element_type beta_; - typename ARRAY_TYPE::element_type limit_; - bool output_convergence_; - unsigned int num_multires_levels_; - unsigned int max_iterations_per_level_; - - private: - std::map>>> phase_images_; - std::vector image_dimensions_; - unsigned short number_of_phases_; - }; -} - -#endif //RegistrationScatteringGadget_H diff --git a/gadgets/moco/config/CMakeLists.txt b/gadgets/moco/config/CMakeLists.txt deleted file mode 100644 index c4add3fff..000000000 --- a/gadgets/moco/config/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -if(CUDA_FOUND) - if(CPU_REG) - install (FILES - cpureg_cartesian_averaging.xml - DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) - endif() - - if(GPU_REG) - install (FILES - gpureg_cartesian_averaging.xml - DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) - endif() -endif() diff --git a/gadgets/moco/config/cpureg_cartesian_averaging.xml b/gadgets/moco/config/cpureg_cartesian_averaging.xml deleted file mode 100644 index 3c00941e8..000000000 --- a/gadgets/moco/config/cpureg_cartesian_averaging.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - NoiseAdjust - pingvin_mricore - NoiseAdjustGadget - - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out16 - - - - CartesianToGenericGadget - pingvin_cartesian - CartesianToGenericGadget - - matrix_size_as_a_multiple_of32 - - - - gpuGenericSensePrepGadget - pingvin_gpuparallelmri - gpuGenericSensePrepGadget - deviceno0 - rotations_per_reconstruction8 - buffer_convolution_kernel_width5.5 - buffer_convolution_oversampling_factor1.25 - - - - gpuCgSenseGadget - pingvin_gpuparallelmri - gpuCgSenseGadget - deviceno 0 - setno 0 - number_of_iterations 20 - cg_limit 1e-6 - oversampling_factor 1.25 - kernel_width 5.5 - kappa 0.05 - output_convergencetrue - - - - PhysioInterpolationGadget - pingvin_mricore - PhysioInterpolationGadget - mode0 - phase30 - - - - Extract - pingvin_mricore - ExtractGadget - - - - cpuRegistrationAveragingGadget2D - pingvin_moco - cpuRegistrationAveragingGadget2D - alpha0.05 - beta1.0 - num_multiresolution_levels3 - output_convergencetrue - phasephase@PhysioInterpolationGadget - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/moco/config/gpureg_cartesian_averaging.xml b/gadgets/moco/config/gpureg_cartesian_averaging.xml deleted file mode 100644 index 89c57b642..000000000 --- a/gadgets/moco/config/gpureg_cartesian_averaging.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - NoiseAdjust - pingvin_mricore - NoiseAdjustGadget - - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out16 - - - - CartesianToGenericGadget - pingvin_cartesian - CartesianToGenericGadget - - matrix_size_as_a_multiple_of32 - - - - gpuGenericSensePrepGadget - pingvin_gpuparallelmri - gpuGenericSensePrepGadget - deviceno0 - rotations_per_reconstruction8 - buffer_convolution_kernel_width5.5 - buffer_convolution_oversampling_factor1.25 - - - - gpuCgSenseGadget - pingvin_gpuparallelmri - gpuCgSenseGadget - deviceno 0 - setno 0 - number_of_iterations 20 - cg_limit 1e-6 - oversampling_factor 1.25 - kernel_width 5.5 - kappa 0.05 - output_convergencetrue - - - - PhysioInterpolationGadget - pingvin_mricore - PhysioInterpolationGadget - mode0 - phase30 - - - - Extract - pingvin_mricore - ExtractGadget - - - - gpuRegistrationAveragingGadget2D - pingvin_moco - gpuRegistrationAveragingGadget2D - alpha0.05 - beta1.0 - num_multiresolution_levels3 - output_convergencetrue - phasephase@PhysioInterpolationGadget - - - - AutoScale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/moco/cpuRegistrationAveragingGadget.cpp b/gadgets/moco/cpuRegistrationAveragingGadget.cpp deleted file mode 100644 index e3eed474a..000000000 --- a/gadgets/moco/cpuRegistrationAveragingGadget.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "cpuRegistrationAveragingGadget.h" -#include "hoLinearResampleOperator.h" -#include "hoCKOpticalFlowSolver.h" - -namespace Gadgetron{ - - int cpuRegistrationAveragingGadget2D::setup_solver() - { - // Allocate solver - hoCKOpticalFlowSolver *solver = new hoCKOpticalFlowSolver(); - this->of_solver_ = solver; - - // Use bilinear resampling for interpolation - solver->set_interpolator( boost::shared_ptr< hoLinearResampleOperator >(new hoLinearResampleOperator()) ); - - // Configurable settings from the xml propoerties - // - - if( this->output_convergence_ ) - solver->set_output_mode( hoCKOpticalFlowSolver::OUTPUT_VERBOSE ); - else - solver->set_output_mode( hoCKOpticalFlowSolver::OUTPUT_SILENT ); - - solver->set_num_multires_levels(this->num_multires_levels_); - solver->set_max_num_iterations_per_level(this->max_iterations_per_level_); - solver->set_alpha(this->alpha_); - solver->set_beta(this->beta_); - solver->set_limit(this->limit_); - - return GADGET_OK; - } - - int cpuRegistrationAveragingGadget2D::set_continuation - ( GadgetContainerMessage* m1, hoNDArray *continuation ) - { - GadgetContainerMessage< hoNDArray > *m2 = new GadgetContainerMessage< hoNDArray >(); - *m2->getObjectPtr() = *continuation; - m1->cont(m2); - - return GADGET_OK; - } - - GADGET_FACTORY_DECLARE(cpuRegistrationAveragingGadget2D) -} diff --git a/gadgets/moco/cpuRegistrationAveragingGadget.h b/gadgets/moco/cpuRegistrationAveragingGadget.h deleted file mode 100644 index bc50e4ee3..000000000 --- a/gadgets/moco/cpuRegistrationAveragingGadget.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef cpuRegistrationAveragingGadget_H -#define cpuRegistrationAveragingGadget_H - -#include "hoNDArray_math.h" -#include "hoNDArray_utils.h" -#include "hoCKOpticalFlowSolver.h" -#include "RegistrationAveragingGadget.h" - -namespace Gadgetron{ - - class cpuRegistrationAveragingGadget2D : - public RegistrationAveragingGadget< hoNDArray, 2 > - { - public: - cpuRegistrationAveragingGadget2D() : RegistrationAveragingGadget< hoNDArray, 2 >() {} - virtual ~cpuRegistrationAveragingGadget2D() {} - - protected: - virtual int setup_solver(); - virtual int set_continuation( GadgetContainerMessage *m1, hoNDArray *continuation ); - }; -} - -#endif //cpuRegistrationAveragingGadget_H diff --git a/gadgets/moco/gpuRegistrationAveragingGadget.cpp b/gadgets/moco/gpuRegistrationAveragingGadget.cpp deleted file mode 100644 index 4f161289b..000000000 --- a/gadgets/moco/gpuRegistrationAveragingGadget.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "gpuRegistrationAveragingGadget.h" -#include "cuLinearResampleOperator.h" -#include "cuCKOpticalFlowSolver.h" - -namespace Gadgetron{ - - int gpuRegistrationAveragingGadget2D::setup_solver() - { - // Allocate solver - cuCKOpticalFlowSolver *solver = new cuCKOpticalFlowSolver(); - this->of_solver_ = solver; - - // Use bilinear resampling for interpolation - solver->set_interpolator( boost::shared_ptr< cuLinearResampleOperator >(new cuLinearResampleOperator()) ); - - // Configurable settings from the xml propoerties - // - - if( this->output_convergence_ ) - solver->set_output_mode( cuCKOpticalFlowSolver::OUTPUT_VERBOSE ); - else - solver->set_output_mode( cuCKOpticalFlowSolver::OUTPUT_SILENT ); - - solver->set_num_multires_levels(this->num_multires_levels_); - solver->set_max_num_iterations_per_level(this->max_iterations_per_level_); - solver->set_alpha(this->alpha_); - solver->set_beta(this->beta_); - solver->set_limit(this->limit_); - - return GADGET_OK; - } - - int gpuRegistrationAveragingGadget2D::set_continuation - ( GadgetContainerMessage* m1, cuNDArray *continuation ) - { - GadgetContainerMessage< hoNDArray > *m2 = new GadgetContainerMessage< hoNDArray >(); - m2->getObjectPtr()->create(continuation->dimensions()); - - if( cudaMemcpy( m2->getObjectPtr()->get_data_ptr(), continuation->get_data_ptr(), - continuation->get_number_of_elements()*sizeof(float), cudaMemcpyDeviceToHost) != cudaSuccess) { - throw cuda_error("gpuRegistrationAveragingGadget::set_continuation(): failed to copy memory from device"); - } - - m1->cont(m2); - - return GADGET_OK; - } - - GADGET_FACTORY_DECLARE(gpuRegistrationAveragingGadget2D) -} diff --git a/gadgets/moco/gpuRegistrationAveragingGadget.h b/gadgets/moco/gpuRegistrationAveragingGadget.h deleted file mode 100644 index 49e1f6314..000000000 --- a/gadgets/moco/gpuRegistrationAveragingGadget.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef gpuRegistrationAveragingGadget_H -#define gpuRegistrationAveragingGadget_H - -#include "cuNDArray_operators.h" -#include "cuNDArray_utils.h" -#include "cuCKOpticalFlowSolver.h" -#include "RegistrationAveragingGadget.h" - -namespace Gadgetron{ - - class gpuRegistrationAveragingGadget2D : - public RegistrationAveragingGadget< cuNDArray, 2 > - { - public: - gpuRegistrationAveragingGadget2D() : RegistrationAveragingGadget< cuNDArray, 2 >() {} - virtual ~gpuRegistrationAveragingGadget2D() {} - - protected: - virtual int setup_solver(); - virtual int set_continuation( GadgetContainerMessage *m1, cuNDArray *continuation ); - }; -} - -#endif //gpuRegistrationAveragingGadget_H diff --git a/gadgets/moco/gpuRegistrationScatteringGadget.cpp b/gadgets/moco/gpuRegistrationScatteringGadget.cpp deleted file mode 100644 index ab63f6b4f..000000000 --- a/gadgets/moco/gpuRegistrationScatteringGadget.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "gpuRegistrationScatteringGadget.h" -#include "cuLinearResampleOperator.h" -#include "cuCKOpticalFlowSolver.h" -#include "hoNDArray_fileio.h" - -namespace Gadgetron{ - - int gpuRegistrationScatteringGadget2D::setup_solver() - { - // Allocate solver - cuCKOpticalFlowSolver *solver = new cuCKOpticalFlowSolver(); - this->of_solver_ = solver; - - // Use bilinear resampling for interpolation - solver->set_interpolator( boost::shared_ptr< cuLinearResampleOperator >(new cuLinearResampleOperator()) ); - - // Configurable settings from the xml propoerties - // - - if( this->output_convergence_ ) - solver->set_output_mode( cuCKOpticalFlowSolver::OUTPUT_VERBOSE ); - else - solver->set_output_mode( cuCKOpticalFlowSolver::OUTPUT_SILENT ); - - solver->set_num_multires_levels(this->num_multires_levels_); - solver->set_max_num_iterations_per_level(this->max_iterations_per_level_); - solver->set_alpha(this->alpha_); - solver->set_beta(this->beta_); - solver->set_limit(this->limit_); - - return GADGET_OK; - } - - int gpuRegistrationScatteringGadget2D::set_continuation - ( GadgetContainerMessage* m1, cuNDArray *continuation ) - { - GadgetContainerMessage< hoNDArray > *m2 = new GadgetContainerMessage< hoNDArray >(); - m2->getObjectPtr()->create(continuation->dimensions()); - - if( cudaMemcpy( m2->getObjectPtr()->get_data_ptr(), continuation->get_data_ptr(), - continuation->get_number_of_elements()*sizeof(float), cudaMemcpyDeviceToHost) != cudaSuccess) { - throw cuda_error("gpuRegistrationScatteringGadget::set_continuation(): failed to copy memory from device"); - } - - m1->cont(m2); - - return GADGET_OK; - } - - int gpuRegistrationScatteringGadget2D::write_displacement_field( cuNDArray *displacements ) - { - write_nd_array(displacements->to_host().get(), "displacement_field_from_scattering_gadget.real"); - return GADGET_OK; - } - - GADGET_FACTORY_DECLARE(gpuRegistrationScatteringGadget2D) -} diff --git a/gadgets/moco/gpuRegistrationScatteringGadget.h b/gadgets/moco/gpuRegistrationScatteringGadget.h deleted file mode 100644 index fd662f81b..000000000 --- a/gadgets/moco/gpuRegistrationScatteringGadget.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef gpuRegistrationScatteringGadget_H -#define gpuRegistrationScatteringGadget_H - -#include "cuNDArray_operators.h" -#include "cuNDArray_utils.h" -#include "cuCKOpticalFlowSolver.h" -#include "RegistrationScatteringGadget.h" - -namespace Gadgetron{ - - class gpuRegistrationScatteringGadget2D : - public RegistrationScatteringGadget< cuNDArray, 2 > - { - public: - gpuRegistrationScatteringGadget2D() : RegistrationScatteringGadget< cuNDArray, 2 >() {} - virtual ~gpuRegistrationScatteringGadget2D() {} - - protected: - virtual int setup_solver(); - virtual int set_continuation( GadgetContainerMessage *m1, cuNDArray *continuation ); - virtual int write_displacement_field( cuNDArray *displacements ); - }; -} - -#endif //gpuRegistrationScatteringGadget_H diff --git a/gadgets/mri_core/CMakeLists.txt b/gadgets/mri_core/CMakeLists.txt index 86d6dbea5..95f0ecbe7 100644 --- a/gadgets/mri_core/CMakeLists.txt +++ b/gadgets/mri_core/CMakeLists.txt @@ -146,15 +146,12 @@ set(pingvin_mricore_generic_recon_gadgets_config_files generic_recon_gadgets/config/Generic_Cartesian_Grappa_EPI_AVE.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa_EPI.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa_ImageArray.xml - generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine_Cloud.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa_SNR.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa_T2W.xml generic_recon_gadgets/config/Generic_Cartesian_Grappa.xml generic_recon_gadgets/config/Generic_Cartesian_Image_Chain_FFT.xml - generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine_Cloud.xml generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine.xml - generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine_Cloud.xml generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine.xml generic_recon_gadgets/config/Generic_Cartesian_Spirit_RealTimeCine.xml generic_recon_gadgets/config/Generic_Cartesian_Spirit_SASHA.xml diff --git a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine_Cloud.xml b/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine_Cloud.xml deleted file mode 100644 index c104b86e1..000000000 --- a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_Grappa_RealTimeCine_Cloud.xml +++ /dev/null @@ -1,227 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosetrue - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres-1 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressiontrue - downstream_coil_compression_thres0.002 - downstream_coil_compression_num_modesKept0 - - - debug_folder - perform_timingtrue - verbosetrue - - - send_out_gfactortrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine_Cloud.xml b/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine_Cloud.xml deleted file mode 100644 index 1fed84daa..000000000 --- a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_NonLinear_Spirit_RealTimeCine_Cloud.xml +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosefalse - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosefalse - - - average_all_ref_Ntrue - - average_all_ref_Strue - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosefalse - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres0.001 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianNonLinearSpirit2DTGadget - - - image_series0 - - - coil_map_algorithmInati - - - spirit_parallel_imaging_lamda1.0 - spirit_data_fidelity_lamda1.0 - spirit_image_reg_lamda0.0015 - spirit_reg_namedb1 - spirit_reg_level1 - spirit_reg_keep_approx_coefftrue - spirit_reg_keep_redundant_dimension_coefffalse - spirit_reg_proximity_across_chafalse - spirit_reg_use_coil_sen_mapfalse - spirit_reg_RO_weighting_ratio1.0 - spirit_reg_E1_weighting_ratio1.0 - spirit_reg_N_weighting_ratio10 - spirit_reg_estimate_noise_floortrue - spirit_reg_minimal_num_images_for_noise_floor16 - spirit_print_itertrue - - - debug_folder - perform_timingtrue - verbosetrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - - PhysioInterpolation - pingvin_mricore - PhysioInterpolationGadget - phases30 - - - mode0 - first_beat_on_triggertrue - - interp_methodBSpline - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine_Cloud.xml b/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine_Cloud.xml deleted file mode 100644 index f62742401..000000000 --- a/gadgets/mri_core/generic_recon_gadgets/config/Generic_Cartesian_RandomSampling_NonLinear_Spirit_RealTimeCine_Cloud.xml +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - Distribute - pingvin_distributed - IsmrmrdAcquisitionDistributeGadget - parallel_dimensionslice - use_this_node_for_computefalse - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Strue - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosefalse - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres0.001 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianNonLinearSpirit2DTGadget - - - image_series0 - - - coil_map_algorithmInati - - - spirit_parallel_imaging_lamda1.0 - spirit_data_fidelity_lamda1.0 - spirit_image_reg_lamda0.0001 - spirit_reg_namedb2 - spirit_reg_level1 - spirit_reg_keep_approx_coefftrue - spirit_reg_keep_redundant_dimension_coefffalse - spirit_reg_proximity_across_chafalse - spirit_reg_use_coil_sen_mapfalse - spirit_reg_RO_weighting_ratio1.0 - spirit_reg_E1_weighting_ratio1.0 - spirit_reg_N_weighting_ratio10 - spirit_reg_estimate_noise_floorfalse - spirit_reg_minimal_num_images_for_noise_floor16 - spirit_print_itertrue - - - debug_folder - perform_timingtrue - verbosetrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - Collect - pingvin_distributed - CollectGadget - - - - - PhysioInterpolation - pingvin_mricore - PhysioInterpolationGadget - phases30 - - - mode0 - first_beat_on_triggertrue - - interp_methodBSpline - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/mri_noncartesian/CMakeLists.txt b/gadgets/mri_noncartesian/CMakeLists.txt deleted file mode 100644 index 9ec1cfcac..000000000 --- a/gadgets/mri_noncartesian/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -set( pingvin_mri_noncartesian_header_files - CPUGriddingReconGadget.h NonCartesianTools.h GriddingReconGadgetBase.h GriddingReconGadgetBase.hpp) - -set( pingvin_mri_noncartesian_src_files - CPUGriddingReconGadget.cpp NonCartesianTools.cpp) - -set( pingvin_mri_noncartesian_config_files - config/Generic_CPU_Gridding_Recon.xml - config/Generic_Spiral.xml - config/Generic_Spiral_SNR.xml - config/Generic_Spiral_Flag.xml - ) - - -if(CUDA_FOUND) - list(APPEND pingvin_mri_noncartesian_header_files GriddingReconGadget.h) - list(APPEND pingvin_mri_noncartesian_src_files GriddingReconGadget.cpp) - - list(APPEND pingvin_mri_noncartesian_config_files config/Generic_Spiral.xml config/Generic_Spiral_SNR.xml) - -endif() - -add_library(pingvin_mri_noncartesian SHARED - ${pingvin_mri_noncartesian_header_files} - ${pingvin_mri_noncartesian_src_files} - ${pingvin_mri_noncartesian_config_files} -) - -set_target_properties(pingvin_mri_noncartesian PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_mri_noncartesian - pingvin_core - pingvin_toolbox_log - pingvin_toolbox_mri_core - pingvin_mricore - pingvin_toolbox_cpucore - pingvin_toolbox_cpufft - pingvin_toolbox_cpunfft - pingvin_toolbox_mri_core - pingvin_toolbox_cpuoperator - pingvin_toolbox_image_analyze_io - - -) -if(CUDA_FOUND) - target_link_libraries(pingvin_mri_noncartesian - pingvin_toolbox_gpu - ) -endif() - -install(FILES - ${pingvin_mri_noncartesian_header_files} - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - -install(TARGETS pingvin_mri_noncartesian - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install(FILES ${pingvin_mri_noncartesian_config_files} DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/mri_noncartesian/CPUGriddingReconGadget.cpp b/gadgets/mri_noncartesian/CPUGriddingReconGadget.cpp deleted file mode 100644 index e7c09bbdc..000000000 --- a/gadgets/mri_noncartesian/CPUGriddingReconGadget.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "CPUGriddingReconGadget.h" -#include "mri_core_grappa.h" -#include "vector_td_utilities.h" -#include -#include -#include "hoNFFT.h" -#include "hoNDArray.h" -#include "hoNDArray_elemwise.h" -#include "hoNDArray_math.h" -#include "hoCgSolver.h" -#include "ImageArraySendMixin.h" -#include -#include -#include "NonCartesianTools.h" -#include "NFFTOperator.h" -#include "hoNDArray_converter.h" -#include "GriddingReconGadgetBase.hpp" - -namespace Gadgetron{ - - - CPUGriddingReconGadget::CPUGriddingReconGadget() { - - } - - CPUGriddingReconGadget::~CPUGriddingReconGadget() { - - } - - GADGET_FACTORY_DECLARE(CPUGriddingReconGadget); -} diff --git a/gadgets/mri_noncartesian/CPUGriddingReconGadget.h b/gadgets/mri_noncartesian/CPUGriddingReconGadget.h deleted file mode 100644 index cd19de492..000000000 --- a/gadgets/mri_noncartesian/CPUGriddingReconGadget.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - \brief CPU Gridding reconstruction gadget - - Handles reconstruction of 2D float data with - density compensation provided. Iterative reconstruction - can be easily integrated -*/ - -#pragma once -#include "generic_recon_gadgets/GenericReconGadget.h" -#include "hoNDArray.h" -#include "GriddingReconGadgetBase.h" - -namespace Gadgetron{ - - class CPUGriddingReconGadget :public GriddingReconGadgetBase { - - public: - - CPUGriddingReconGadget(); - - ~CPUGriddingReconGadget(); - }; -} diff --git a/gadgets/mri_noncartesian/GriddingReconGadget.cpp b/gadgets/mri_noncartesian/GriddingReconGadget.cpp deleted file mode 100644 index c445a033f..000000000 --- a/gadgets/mri_noncartesian/GriddingReconGadget.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Created by dchansen on 10/25/18. -// - -#include "GriddingReconGadget.h" -#include "cuNFFT.h" -#include "cuNDArray_converter.h" - #include "b1_map.h" -#include "GriddingReconGadgetBase.hpp" - -namespace Gadgetron { - GriddingReconGadget::GriddingReconGadget() : GriddingReconGadgetBase() { - - } - - GriddingReconGadget::~GriddingReconGadget() { - - } - - GADGET_FACTORY_DECLARE(GriddingReconGadget); -} \ No newline at end of file diff --git a/gadgets/mri_noncartesian/GriddingReconGadget.h b/gadgets/mri_noncartesian/GriddingReconGadget.h deleted file mode 100644 index 8a9dd28b5..000000000 --- a/gadgets/mri_noncartesian/GriddingReconGadget.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "GriddingReconGadgetBase.h" -#include "cuNDArray.h" -#include "cuNDArray_math.h" - -namespace Gadgetron { - class GriddingReconGadget : public GriddingReconGadgetBase { - public: - GriddingReconGadget(); - ~GriddingReconGadget(); - }; - - -} - - diff --git a/gadgets/mri_noncartesian/GriddingReconGadgetBase.h b/gadgets/mri_noncartesian/GriddingReconGadgetBase.h deleted file mode 100644 index c5d24596f..000000000 --- a/gadgets/mri_noncartesian/GriddingReconGadgetBase.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "generic_recon_gadgets/GenericReconGadget.h" - -namespace Gadgetron { - - template class ARRAY> - class GriddingReconGadgetBase : public ImageArraySendMixin>, public Gadget1 - { - public: - GriddingReconGadgetBase(); - ~GriddingReconGadgetBase(); - - - GADGET_PROPERTY(kernel_width,float,"Kernel width for NFFT", 5.5); - GADGET_PROPERTY(gridding_oversampling_factor,float,"Oversampling used in NFFT", 1.5); - GADGET_PROPERTY(iterate,bool,"Iterate instead of using weights", false); - GADGET_PROPERTY(iteration_max,int,"Maximum number of iterations", 5); - GADGET_PROPERTY(iteration_tol,float,"Iteration tolerance", 1e-5); - GADGET_PROPERTY(replicas, int,"Number of pseudo replicas", 0); - GADGET_PROPERTY(snr_frame, int,"Frame number for SNR measurement", 20); - GADGET_PROPERTY(perform_timing, bool,"Perform timing", false); - GADGET_PROPERTY(image_series,int,"Image Series",1); - GADGET_PROPERTY(verbose, bool,"Verbose", false); - protected: - float kernel_width_; - float oversampling_factor_; - int ncoils_; - - unsigned int process_called_times=0; - - std::vector image_dims_; - uint64d2 image_dims_os_; - - virtual int process_config(ACE_Message_Block* mb) override; - virtual int process(Gadgetron::GadgetContainerMessage< IsmrmrdReconData >* m1) override; - - void pseudo_replica(const hoNDArray>& data, - ARRAY& traj,ARRAY& dcw, const ARRAY& csm, - const IsmrmrdReconBit& recon_bit, size_t encoding, size_t ncoils); - - boost::shared_ptr > reconstruct( - ARRAY* data, - ARRAY* traj, - ARRAY* dcw, - size_t ncoils ); - - std::tuple >, boost::shared_ptr>> separate_traj_and_dcw(hoNDArray* traj_dcw); - - }; -} - -#include "GriddingReconGadgetBase.hpp" diff --git a/gadgets/mri_noncartesian/GriddingReconGadgetBase.hpp b/gadgets/mri_noncartesian/GriddingReconGadgetBase.hpp deleted file mode 100644 index c28cd4146..000000000 --- a/gadgets/mri_noncartesian/GriddingReconGadgetBase.hpp +++ /dev/null @@ -1,293 +0,0 @@ -#pragma once -#include "GriddingReconGadgetBase.h" -#include "mri_core_grappa.h" - -#include "vector_td_utilities.h" -#include -#include -#include "cgSolver.h" -#include "hoNDArray_math.h" -#include "hoNDArray_utils.h" -#include -#include -#include "NonCartesianTools.h" -#include "NFFTOperator.h" - -namespace Gadgetron { - -template class ARRAY> GriddingReconGadgetBase::GriddingReconGadgetBase() : Gadget1() {} -template class ARRAY> GriddingReconGadgetBase::~GriddingReconGadgetBase() {} -template class ARRAY> int GriddingReconGadgetBase::process_config(ACE_Message_Block* mb) - { - // ------------------------------------------------- - - ISMRMRD::IsmrmrdHeader h; - deserialize(mb->rd_ptr(), h); - - - auto matrixsize = h.encoding.front().encodedSpace.matrixSize; - - - kernel_width_ = kernel_width.value(); - oversampling_factor_ = gridding_oversampling_factor.value(); - - - image_dims_.push_back(matrixsize.x); - image_dims_.push_back(matrixsize.y); - - //Figure out what the oversampled matrix size should be taking the warp size into consideration. - unsigned int warp_size = 32; - image_dims_os_ = uint64d2 - (((static_cast(std::ceil(image_dims_[0]*oversampling_factor_))+warp_size-1)/warp_size)*warp_size, - ((static_cast(std::ceil(image_dims_[1]*oversampling_factor_))+warp_size-1)/warp_size)*warp_size); - - // In case the warp_size constraint kicked in - oversampling_factor_ = float(image_dims_os_[0])/float(image_dims_[0]); - this->initialize_encoding_space_limits(h); - - return GADGET_OK; - } - -template class ARRAY> int GriddingReconGadgetBase::process(Gadgetron::GadgetContainerMessage< IsmrmrdReconData >* m1) - { - - std::unique_ptr timer; - if (perform_timing) { timer = std::make_unique("Gridding Recon");} - process_called_times++; - - - IsmrmrdReconData* recon_bit_ = m1->getObjectPtr(); - - - // for every encoding space - for (size_t e = 0; e < recon_bit_->rbit_.size(); e++) - { - - mrd::ReconBuffer* buffer = &(recon_bit_->rbit_[e].data_); - - size_t RO = buffer->data_.get_size(0); - size_t E1 = buffer->data_.get_size(1); - size_t E2 = buffer->data_.get_size(2); - size_t CHA = buffer->data_.get_size(3); - size_t N = buffer->data_.get_size(4); - size_t S = buffer->data_.get_size(5); - size_t SLC = buffer->data_.get_size(6); - - if (E2 > 1) { - GERROR("3D data is not supported in GriddingReconGadgetBase\n"); - m1->release(); - return GADGET_FAIL; - } - - if (buffer->trajectory_ == std::nullopt) { - GERROR("Trajectories not found. Bailing out.\n"); - m1->release(); - return GADGET_FAIL; - } - - - std::vector new_order = {0,1,2,4,5,6,3}; - - boost::shared_ptr> dcw; - boost::shared_ptr> traj; - - auto & trajectory = *buffer->trajectory_; - - if (buffer->headers_[0].trajectory_dimensions == 3){ - auto traj_dcw = separate_traj_and_dcw(&trajectory); - dcw = boost::make_shared>(*std::get<1>(traj_dcw).get()); - traj = boost::make_shared>(*std::get<0>(traj_dcw).get()); - } else if (buffer->headers_[0].trajectory_dimensions == 2){ - auto old_traj_dims = trajectory.get_dimensions(); - std::vector traj_dims (old_traj_dims.begin()+1,old_traj_dims.end()); //Remove first element - hoNDArray tmp_traj(traj_dims,(floatd2*)trajectory.get_data_ptr()); - traj = boost::make_shared>(tmp_traj); - } else { - throw std::runtime_error("Unsupported number of trajectory dimensions"); - } - - auto permuted = permute(*(hoNDArray*)&buffer->data_,new_order); - ARRAY data(permuted); - - if (dcw){ - float scale_factor = float(prod(image_dims_os_))/asum(dcw.get()); - *dcw *= scale_factor; - } - - //Gridding - auto images = reconstruct(&data,traj.get(),dcw.get(),CHA); - - //Calculate coil sensitivity map - auto csm = estimate_b1_map(*images); - - //Coil combine - *images *= *conj(&csm); - auto combined = sum(images.get(),images->get_number_of_dimensions()-1); - - auto host_img = as_hoNDArray(combined); - - IsmrmrdImageArray imarray; - - auto elements = imarray.data_.get_number_of_elements(); - imarray.data_ = std::move(*boost::reinterpret_pointer_cast(host_img)); -// memcpy(imarray.data_.get_data_ptr(), host_img->get_data_ptr(), host_img->get_number_of_bytes()); - - NonCartesian::append_image_header(imarray,recon_bit_->rbit_[e], e); - this->prepare_image_array(imarray, e, ((int)e + 1), GADGETRON_IMAGE_REGULAR); - - this->next()->putq(new GadgetContainerMessage(std::move(imarray))); - - - //Is this where we measure SNR? - if (replicas.value() > 0 && snr_frame.value() == process_called_times) { - pseudo_replica(buffer->data_,*traj,*dcw,csm,recon_bit_->rbit_[e],e,CHA); - } - } - - m1->release(); - return GADGET_OK; - } - -template class ARRAY> boost::shared_ptr > GriddingReconGadgetBase::reconstruct( - ARRAY* data, - ARRAY* traj, - ARRAY* dcw, - size_t ncoils ) { - GadgetronTimer timer("Reconstruct"); - //We have density compensation and iteration is set to false - if (!iterate.value() && dcw) { - - auto plan = NFFT::make_plan(from_std_vector(image_dims_),image_dims_os_,kernel_width_); - std::vector recon_dims = image_dims_; - recon_dims.push_back(ncoils); - auto result = new ARRAY(recon_dims); - - std::vector flat_dims = {traj->get_number_of_elements()}; - ARRAY flat_traj(flat_dims,traj->get_data_ptr()); - - - plan->preprocess(flat_traj,NFFT_prep_mode::NC2C); - plan->compute(*data,*result,dcw,NFFT_comp_mode::BACKWARDS_NC2C); - - return boost::shared_ptr>(result); - - } else { //No density compensation, we have to do iterative reconstruction. - std::vector recon_dims = image_dims_; - recon_dims.push_back(ncoils); - - auto E = boost::make_shared>(); - - auto data_cpy = data; - - E->setup(from_std_vector(image_dims_),image_dims_os_,kernel_width_); - if (dcw){ - auto dcw_sqrt = boost::make_shared>(*dcw); - sqrt_inplace(dcw_sqrt.get()); - E->set_dcw(boost::make_shared>(*dcw_sqrt)); - data_cpy = new ARRAY(*data); - *data_cpy *= *dcw_sqrt; - } - std::vector flat_dims = {traj->get_number_of_elements()}; - ARRAY flat_traj(flat_dims,traj->get_data_ptr()); - - E->set_domain_dimensions(recon_dims); - cgSolver> solver; - solver.set_max_iterations(iteration_max.value()); - solver.set_encoding_operator(E); - solver.set_tc_tolerance(iteration_tol.value()); - solver.set_output_mode(decltype(solver)::OUTPUT_SILENT); - E->set_codomain_dimensions(data->get_dimensions()); - E->preprocess(flat_traj); - auto res = solver.solve(data_cpy); - - if (dcw) delete data_cpy; - - return res; - } - } - - -template class ARRAY> std::tuple >, boost::shared_ptr>> GriddingReconGadgetBase::separate_traj_and_dcw( - hoNDArray* traj_dcw) { - std::vector dims = traj_dcw->get_dimensions(); - std::vector reduced_dims(dims.begin()+1,dims.end()); //Copy vector, but leave out first dim - auto dcw = boost::make_shared>(reduced_dims); - - auto traj = boost::make_shared>(reduced_dims); - - auto dcw_ptr = dcw->get_data_ptr(); - auto traj_ptr = traj->get_data_ptr(); - auto ptr = traj_dcw->get_data_ptr(); - for (size_t i = 0; i < traj_dcw->get_number_of_elements()/3; i++){ - traj_ptr[i][0] = ptr[i*3]; - traj_ptr[i][1] = ptr[i*3+1]; - dcw_ptr[i] = ptr[i*3+2]; - } - - return std::make_tuple(traj,dcw); - } - -template class ARRAY> void GriddingReconGadgetBase::pseudo_replica(const hoNDArray>& data, - ARRAY& traj,ARRAY& dcw, const ARRAY& csm, - const IsmrmrdReconBit& recon_bit, size_t encoding, size_t ncoils) { - hoNDArray > rep_array(image_dims_[0], image_dims_[1], replicas.value()); - - std::mt19937 engine; - std::normal_distribution distribution; - - for (size_t r = 0; r < replicas.value(); ++r) { - - if (r % 10 == 0) { - GDEBUG("Running pseudo replics %d of %d\n", r, replicas.value()); - } - hoNDArray > dtmp = data; - std::vector new_order = {0,1,2,4,5,6,3}; - auto permuted_rep = permute(*(hoNDArray*)&dtmp,new_order); - auto dataptr = permuted_rep.get_data_ptr(); - - for (size_t k =0; k < permuted_rep.get_number_of_elements(); k++){ - dataptr[k] += std::complex(distribution(engine),distribution(engine)); - } - - ARRAY data_rep(permuted_rep); - - auto images = reconstruct(&data_rep,&traj,&dcw,ncoils); - - //Coil combine - *images *= *conj(&csm); - auto combined = sum(images.get(),images->get_number_of_dimensions()-1); - - auto host_img = as_hoNDArray(combined); - - size_t offset = image_dims_[0]*image_dims_[1]*r; - - memcpy(rep_array.get_data_ptr()+offset, host_img->get_data_ptr(), host_img->get_number_of_bytes()); - } - - - hoNDArray mag(rep_array.dimensions()); - hoNDArray mean(image_dims_[0],image_dims_[1]); - hoNDArray std(image_dims_[0],image_dims_[1]); - - Gadgetron::abs(rep_array, mag); - Gadgetron::sum_over_dimension(mag,mean,2); - Gadgetron::scal(1.0f/replicas.value(), mean); - - mag -= mean; - mag *= mag; - - Gadgetron::sum_over_dimension(mag,std,2); - Gadgetron::scal(1.0f/(replicas.value()-1), std); - Gadgetron::sqrt_inplace(&std); - - //SNR image - mean /= std; - IsmrmrdImageArray imarray; - imarray.data_ = *real_to_complex< std::complex >(&mean); - - NonCartesian::append_image_header(imarray,recon_bit, encoding); - this->prepare_image_array(imarray, encoding, image_series + 100 * ((int)encoding + 3), GADGETRON_IMAGE_SNR_MAP); - this->next()->putq(new GadgetContainerMessage(imarray)); - } - -} diff --git a/gadgets/mri_noncartesian/NonCartesianTools.cpp b/gadgets/mri_noncartesian/NonCartesianTools.cpp deleted file mode 100644 index e9b7dff51..000000000 --- a/gadgets/mri_noncartesian/NonCartesianTools.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// -// Created by dchansen on 10/23/18. -// - -#include "NonCartesianTools.h" - -void Gadgetron::NonCartesian::append_image_header( IsmrmrdImageArray &res, const IsmrmrdReconBit &recon_bit,size_t encoding) { - - size_t RO = res.data_.get_size(0); - size_t E1 = res.data_.get_size(1); - size_t E2 = res.data_.get_size(2); - size_t CHA = res.data_.get_size(3); - size_t N = res.data_.get_size(4); - size_t S = res.data_.get_size(5); - size_t SLC = res.data_.get_size(6); - - - res.headers_.create(N, S, SLC); - res.meta_.resize(N * S * SLC); - - size_t n, s, slc; - - for (slc = 0; slc < SLC; slc++) { - for (s = 0; s < S; s++) { - for (n = 0; n < N; n++) { - - const ISMRMRD::AcquisitionHeader &acq_header = recon_bit.data_.headers_(0, 0, n, s, slc); - ISMRMRD::ImageHeader &im_header = res.headers_(n, s, slc); - ISMRMRD::MetaContainer &meta = res.meta_[n + s * N + slc * N * S]; - - im_header.version = acq_header.version; - im_header.data_type = ISMRMRD::ISMRMRD_CXFLOAT; - im_header.flags = acq_header.flags; - im_header.measurement_uid = acq_header.measurement_uid; - - uint16_t matrix_size[3] = {(uint16_t) RO, (uint16_t) E1, (uint16_t) E2}; - std::copy(matrix_size, std::end(matrix_size), im_header.matrix_size); - - std::copy(std::begin(recon_bit.data_.sampling_.recon_FOV_), std::end(recon_bit.data_.sampling_.recon_FOV_), - std::begin(im_header.field_of_view)); - - im_header.channels = (uint16_t) CHA; - - std::copy(acq_header.position, std::end(acq_header.position), im_header.position); - - std::copy(acq_header.read_dir, std::end(acq_header.read_dir), im_header.read_dir); - - std::copy(acq_header.phase_dir, std::end(acq_header.phase_dir), im_header.phase_dir); - std::copy(acq_header.slice_dir, std::end(acq_header.slice_dir), im_header.slice_dir); - std::copy(acq_header.patient_table_position, std::end(acq_header.patient_table_position), - im_header.patient_table_position); - - - im_header.average = acq_header.idx.average; - im_header.slice = acq_header.idx.slice; - im_header.contrast = acq_header.idx.contrast; - im_header.phase = acq_header.idx.phase; - im_header.repetition = acq_header.idx.repetition; - im_header.set = acq_header.idx.set; - - im_header.acquisition_time_stamp = acq_header.acquisition_time_stamp; - - std::copy(acq_header.physiology_time_stamp, std::end(acq_header.physiology_time_stamp), - im_header.physiology_time_stamp); - - im_header.image_type = ISMRMRD::ISMRMRD_IMTYPE_COMPLEX; - im_header.image_index = (uint16_t) (n + s * N + slc * N * S); - im_header.image_series_index = 0; - - std::copy(acq_header.user_float, std::end(acq_header.user_float), im_header.user_float); - std::copy(acq_header.user_int, std::end(acq_header.user_int), im_header.user_int); - - im_header.attribute_string_len = 0; - - meta.set("encoding", (long) encoding); - - meta.set("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[0]); - meta.append("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[1]); - meta.append("encoding_FOV", recon_bit.data_.sampling_.encoded_FOV_[2]); - - meta.set("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[0]); - meta.append("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[1]); - meta.append("recon_FOV", recon_bit.data_.sampling_.recon_FOV_[2]); - - meta.set("encoded_matrix", (long) recon_bit.data_.sampling_.encoded_matrix_[0]); - meta.append("encoded_matrix", (long) recon_bit.data_.sampling_.encoded_matrix_[1]); - meta.append("encoded_matrix", (long) recon_bit.data_.sampling_.encoded_matrix_[2]); - - meta.set("recon_matrix", (long) recon_bit.data_.sampling_.recon_matrix_[0]); - meta.append("recon_matrix", (long) recon_bit.data_.sampling_.recon_matrix_[1]); - meta.append("recon_matrix", (long) recon_bit.data_.sampling_.recon_matrix_[2]); - - meta.set("sampling_limits_RO", (long) recon_bit.data_.sampling_.sampling_limits_[0].min_); - meta.append("sampling_limits_RO", (long) recon_bit.data_.sampling_.sampling_limits_[0].center_); - meta.append("sampling_limits_RO", (long) recon_bit.data_.sampling_.sampling_limits_[0].max_); - - meta.set("sampling_limits_E1", (long) recon_bit.data_.sampling_.sampling_limits_[1].min_); - meta.append("sampling_limits_E1", (long) recon_bit.data_.sampling_.sampling_limits_[1].center_); - meta.append("sampling_limits_E1", (long) recon_bit.data_.sampling_.sampling_limits_[1].max_); - - meta.set("sampling_limits_E2", (long) recon_bit.data_.sampling_.sampling_limits_[2].min_); - meta.append("sampling_limits_E2", (long) recon_bit.data_.sampling_.sampling_limits_[2].center_); - meta.append("sampling_limits_E2", (long) recon_bit.data_.sampling_.sampling_limits_[2].max_); - - meta.set("PatientPosition", (double) res.headers_(n, s, slc).position[0]); - meta.append("PatientPosition", (double) res.headers_(n, s, slc).position[1]); - meta.append("PatientPosition", (double) res.headers_(n, s, slc).position[2]); - - meta.set("read_dir", (double) res.headers_(n, s, slc).read_dir[0]); - meta.append("read_dir", (double) res.headers_(n, s, slc).read_dir[1]); - meta.append("read_dir", (double) res.headers_(n, s, slc).read_dir[2]); - - meta.set("phase_dir", (double) res.headers_(n, s, slc).phase_dir[0]); - meta.append("phase_dir", (double) res.headers_(n, s, slc).phase_dir[1]); - meta.append("phase_dir", (double) res.headers_(n, s, slc).phase_dir[2]); - - meta.set("slice_dir", (double) res.headers_(n, s, slc).slice_dir[0]); - meta.append("slice_dir", (double) res.headers_(n, s, slc).slice_dir[1]); - meta.append("slice_dir", (double) res.headers_(n, s, slc).slice_dir[2]); - - meta.set("patient_table_position", (double) res.headers_(n, s, slc).patient_table_position[0]); - meta.append("patient_table_position", (double) res.headers_(n, s, slc).patient_table_position[1]); - meta.append("patient_table_position", (double) res.headers_(n, s, slc).patient_table_position[2]); - - meta.set("acquisition_time_stamp", (long) res.headers_(n, s, slc).acquisition_time_stamp); - - meta.set("physiology_time_stamp", (long) res.headers_(n, s, slc).physiology_time_stamp[0]); - meta.append("physiology_time_stamp", (long) res.headers_(n, s, slc).physiology_time_stamp[1]); - meta.append("physiology_time_stamp", (long) res.headers_(n, s, slc).physiology_time_stamp[2]); - } - } - } -} - diff --git a/gadgets/mri_noncartesian/NonCartesianTools.h b/gadgets/mri_noncartesian/NonCartesianTools.h deleted file mode 100644 index a3795eafa..000000000 --- a/gadgets/mri_noncartesian/NonCartesianTools.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace Gadgetron { namespace NonCartesian { - - void append_image_header(IsmrmrdImageArray &res, const IsmrmrdReconBit &recon_bit, - size_t encoding); - } -} \ No newline at end of file diff --git a/gadgets/mri_noncartesian/config/Generic_CPU_Gridding_Recon.xml b/gadgets/mri_noncartesian/config/Generic_CPU_Gridding_Recon.xml deleted file mode 100644 index c81e52a94..000000000 --- a/gadgets/mri_noncartesian/config/Generic_CPU_Gridding_Recon.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out8 - - - - - SpiralToGeneric - pingvin_spiral - SpiralToGenericGadget - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionrepetition - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - CPUGriddingRecon - pingvin_mri_noncartesian - CPUGriddingReconGadget - verbosetrue - perform_timingtrue - - - - - - - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/mri_noncartesian/config/Generic_Spiral.xml b/gadgets/mri_noncartesian/config/Generic_Spiral.xml deleted file mode 100644 index 73c91d817..000000000 --- a/gadgets/mri_noncartesian/config/Generic_Spiral.xml +++ /dev/null @@ -1,114 +0,0 @@ - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out16 - - - - - SpiralToGeneric - pingvin_spiral - SpiralToGenericGadget - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionrepetition - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - GriddingRecon - pingvin_mri_noncartesian - GriddingReconGadget - verbosetrue - perform_timingtrue - - - - - - - - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - - - - - - - - - - diff --git a/gadgets/mri_noncartesian/config/Generic_Spiral_Flag.xml b/gadgets/mri_noncartesian/config/Generic_Spiral_Flag.xml deleted file mode 100644 index e3f8dcdf4..000000000 --- a/gadgets/mri_noncartesian/config/Generic_Spiral_Flag.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out16 - - - - - SpiralToGeneric - pingvin_spiral - SpiralToGenericGadget - - - - - AccTrig - pingvin_mricore - FlagTriggerGadget - trigger_flagslast_in_slice || last_in_repetition - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - CPUGriddingRecon - pingvin_mri_noncartesian - CPUGriddingReconGadget - verbosetrue - perform_timingtrue - - - - - - - - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - - - - - - - - - - diff --git a/gadgets/mri_noncartesian/config/Generic_Spiral_SNR.xml b/gadgets/mri_noncartesian/config/Generic_Spiral_SNR.xml deleted file mode 100644 index 8828e41eb..000000000 --- a/gadgets/mri_noncartesian/config/Generic_Spiral_SNR.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - - SpiralToGeneric - pingvin_spiral - SpiralToGenericGadget - - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionrepetition - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - GriddingRecon - pingvin_mri_noncartesian - GriddingReconGadget - verbosetrue - perform_timingtrue - - - iteratetrue - iteration_max10 - iteration_tol1e-3 - - - replicas256 - snr_frame20 - - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/plplot/CMakeLists.txt b/gadgets/plplot/CMakeLists.txt deleted file mode 100644 index 49ba49ee6..000000000 --- a/gadgets/plplot/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -include_directories(${PLPLOT_INCLUDE_DIR}) -link_directories(${PLPLOT_LIB_DIR}) - - -set( header_files NoiseCovariancePlottingGadget.h ) -set( src_files NoiseCovariancePlottingGadget.cpp ) -set( config_files Generic_Cartesian_Grappa_SNR_CoilQA.xml ) - -source_group(config FILES ${config_files}) - -add_library(pingvin_plplot SHARED - ${header_files} - ${src_files} - ${config_files} -) - -set_target_properties(pingvin_plplot PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_plplot - pingvin_core - pingvin_mricore - pingvin_toolbox_log - pingvin_toolbox_cpucore - pingvin_toolbox_plplot -) - -install(FILES - ${header_files} - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) - -install(TARGETS pingvin_plplot - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install (FILES ${config_files} - DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/plplot/Generic_Cartesian_Grappa_SNR_CoilQA.xml b/gadgets/plplot/Generic_Cartesian_Grappa_SNR_CoilQA.xml deleted file mode 100644 index 97ce51da0..000000000 --- a/gadgets/plplot/Generic_Cartesian_Grappa_SNR_CoilQA.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimension - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionrepetition - S_dimensionset - split_slicesfalse - ignore_segmenttrue - verbosetrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Strue - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosetrue - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres0.002 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressiontrue - downstream_coil_compression_thres0.01 - downstream_coil_compression_num_modesKept0 - - - debug_folder - perform_timingtrue - verbosetrue - - - send_out_gfactortrue - send_out_snr_maptrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingFilterGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_filter_RO_width0.15 - partial_fourier_filter_E1_width0.15 - partial_fourier_filter_E2_width0.15 - partial_fourier_filter_densityCompfalse - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - - - StdMap - pingvin_mricore - GenericReconNoiseStdMapComputingGadget - - - debug_folder - perform_timingfalse - verbosetrue - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosetrue - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated1000.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - - NoiseCovariancePlotting - pingvin_plplot - NoiseCovariancePlottingGadget - - xlabelChannel - ylabelSD - titleGadgetron - - xsize768 - ysize768 - - series_num1000 - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - max_intensity32767 - min_intensity0 - intensity_offset0 - - - diff --git a/gadgets/plplot/NoiseCovariancePlottingGadget.cpp b/gadgets/plplot/NoiseCovariancePlottingGadget.cpp deleted file mode 100644 index c861943c6..000000000 --- a/gadgets/plplot/NoiseCovariancePlottingGadget.cpp +++ /dev/null @@ -1,273 +0,0 @@ - -#include "NoiseCovariancePlottingGadget.h" - -#include "GtPLplot.h" - -#include "fstream" - -#include -#include - -#include "mri_core_def.h" -#include "io/primitives.h" - -namespace Gadgetron{ - -NoiseCovariancePlottingGadget::NoiseCovariancePlottingGadget() - : noise_decorrelation_calculated_(false) - , noise_dwell_time_us_(-1.0f) - , noiseCovarianceLoaded_(false) - , noise_dependency_prefix_("GadgetronNoiseCovarianceMatrix") - , noise_dependency_folder_("/tmp/gadgetron/") -{ - measurement_id_.clear(); - measurement_id_of_noise_dependency_.clear(); -} - -NoiseCovariancePlottingGadget::~NoiseCovariancePlottingGadget() -{ - -} - -int NoiseCovariancePlottingGadget::process_config(ACE_Message_Block* mb) -{ - GDEBUG("Folder to store noise dependencies is %s\n", noise_dependency_folder_.c_str()); - - if (!noise_dependency_prefix.value().empty()) noise_dependency_prefix_ = noise_dependency_prefix.value(); - - ISMRMRD::deserialize(mb->rd_ptr(), current_ismrmrd_header_); - - // find the measurementID of this scan - if (current_ismrmrd_header_.measurementInformation) - { - if (current_ismrmrd_header_.measurementInformation->measurementID) - { - measurement_id_ = *current_ismrmrd_header_.measurementInformation->measurementID; - GDEBUG("Measurement ID is %s\n", measurement_id_.c_str()); - } - - // find the noise dependencies if any - if (current_ismrmrd_header_.measurementInformation->measurementDependency.size() > 0) - { - measurement_id_of_noise_dependency_.clear(); - - std::vector::const_iterator iter = current_ismrmrd_header_.measurementInformation->measurementDependency.begin(); - for (; iter != current_ismrmrd_header_.measurementInformation->measurementDependency.end(); iter++) - { - std::string dependencyType = iter->dependencyType; - std::string dependencyID = iter->measurementID; - - GDEBUG("Found dependency measurement : %s with ID %s\n", dependencyType.c_str(), dependencyID.c_str()); - - if (dependencyType == "Noise" || dependencyType == "noise") { - measurement_id_of_noise_dependency_ = dependencyID; - } - } - - if (!measurement_id_of_noise_dependency_.empty()) - { - GDEBUG("Measurement ID of noise dependency is %s\n", measurement_id_of_noise_dependency_.c_str()); - - full_name_stored_noise_dependency_ = this->generateNoiseDependencyFilename(generateMeasurementIdOfNoiseDependency(measurement_id_of_noise_dependency_)); - GDEBUG("Stored noise dependency is %s\n", full_name_stored_noise_dependency_.c_str()); - } - } - else - { - full_name_stored_noise_dependency_ = this->generateNoiseDependencyFilename(measurement_id_); - GDEBUG("Stored noise dependency is %s\n", full_name_stored_noise_dependency_.c_str()); - } - } - - return GADGET_OK; -} - -std::string NoiseCovariancePlottingGadget::generateMeasurementIdOfNoiseDependency(const std::string& noise_id) -{ - //TODO: Remove this hack. This hack addresses a problem with mislabeled noise dependency IDs generated by the converter. - //We will keep this for a transition period while preserving backwards compatibility - if (noise_id.find("_") == std::string::npos) { - // find the scan prefix - std::string measurementStr = measurement_id_; - size_t ind = measurement_id_.find_last_of ("_"); - if ( ind != std::string::npos ) { - measurementStr = measurement_id_.substr(0, ind); - measurementStr.append("_"); - measurementStr.append(noise_id); - } - - return measurementStr; - } - - return noise_id; -} - -std::string NoiseCovariancePlottingGadget::generateNoiseDependencyFilename(const std::string& measurement_id) -{ - std::string full_name_stored_noise_dependency; - - full_name_stored_noise_dependency = noise_dependency_folder_; - full_name_stored_noise_dependency.append("/"); - full_name_stored_noise_dependency.append(noise_dependency_prefix_); - full_name_stored_noise_dependency.append("_"); - full_name_stored_noise_dependency.append(measurement_id); - - return full_name_stored_noise_dependency; -} - -bool NoiseCovariancePlottingGadget::loadNoiseCovariance() -{ - std::ifstream infile; - infile.open(full_name_stored_noise_dependency_.c_str(), std::ios::in | std::ios::binary); - - if (infile.good()) - { - //Read the XML header of the noise scan - uint32_t xml_length; - infile.read(reinterpret_cast(&xml_length), 4); - std::string xml_str(xml_length, '\0'); - infile.read(const_cast(xml_str.c_str()), xml_length); - ISMRMRD::deserialize(xml_str.c_str(), noise_ismrmrd_header_); - - infile.read(reinterpret_cast(&noise_dwell_time_us_), sizeof(float)); - - size_t len; - infile.read(reinterpret_cast(&len), sizeof(size_t)); - - auto buf = std::vector(len); - - infile.read(buf.data(), len); - - noise_covariance_matrixf_ = Core::IO::read>>(infile); - infile.close(); - } - else - { - return false; - } - - return true; -} - -int NoiseCovariancePlottingGadget::process(GadgetContainerMessage* m1, GadgetContainerMessage< hoNDArray< std::complex > >* m2) -{ - curr_image_header_ = *m1->getObjectPtr(); - - if (this->next()->putq(m1) == -1) - { - m1->release(); - GDEBUG("NoiseCovariancePlottingGadget, Unable to put image on next gadgets queue"); - return GADGET_FAIL; - } - - return GADGET_OK; -} - -int NoiseCovariancePlottingGadget::close(unsigned long flags) -{ - if (BaseClass::close(flags) != GADGET_OK) return GADGET_FAIL; - - // try to load the precomputed noise prewhitener - if (flags == 0) return GADGET_OK; - - if (!full_name_stored_noise_dependency_.empty()) - { - if (this->loadNoiseCovariance()) - { - GDEBUG("Stored noise dependency is found : %s\n", full_name_stored_noise_dependency_.c_str()); - - if (noise_ismrmrd_header_.acquisitionSystemInformation.is_present()) - { - hoNDArray plotIm; - - bool trueColor = false; - size_t CHA = noise_covariance_matrixf_.get_size(0); - - std::vector coilStrings(CHA, "Unknown"); - for (size_t n = 0; n < CHA; n++) - { - int coilNum = noise_ismrmrd_header_.acquisitionSystemInformation.get().coilLabel[n].coilNumber; - if (coilNum >= 0 && coilNum < CHA) - { - coilStrings[coilNum] = noise_ismrmrd_header_.acquisitionSystemInformation.get().coilLabel[n].coilName; - } - } - - Gadgetron::plotNoiseStandardDeviation(noise_covariance_matrixf_, coilStrings, xlabel.value(), ylabel.value(), title.value(), xsize.value(), ysize.value(), trueColor, plotIm); - - // send out the noise variance plot - Gadgetron::GadgetContainerMessage* cm1 = new Gadgetron::GadgetContainerMessage(); - Gadgetron::GadgetContainerMessage* cm3 = new Gadgetron::GadgetContainerMessage(); - - *cm1->getObjectPtr() = curr_image_header_; - - cm1->getObjectPtr()->flags = 0; - cm1->getObjectPtr()->data_type = ISMRMRD::ISMRMRD_CXFLOAT; - cm1->getObjectPtr()->image_type = ISMRMRD::ISMRMRD_IMTYPE_MAGNITUDE; - - cm1->getObjectPtr()->image_index = 1; - cm1->getObjectPtr()->image_series_index = series_num.value(); - - Gadgetron::GadgetContainerMessage< Gadgetron::hoNDArray< std::complex > >* cm2 = new Gadgetron::GadgetContainerMessage< Gadgetron::hoNDArray< std::complex > >(); - cm1->cont(cm2); - cm2->cont(cm3); - - std::vector img_dims(2); - img_dims[0] = plotIm.get_size(0); - img_dims[1] = plotIm.get_size(1); - - // set the image attributes - cm3->getObjectPtr()->set(GADGETRON_IMAGECOMMENT, "Noise SD"); - cm3->getObjectPtr()->set(GADGETRON_SEQUENCEDESCRIPTION, "_GT_Noise_SD_Plot"); - cm3->getObjectPtr()->set(GADGETRON_IMAGEPROCESSINGHISTORY, "GT"); - cm3->getObjectPtr()->set(GADGETRON_DATA_ROLE, GADGETRON_IMAGE_RECON_FIGURE); - - cm3->getObjectPtr()->set(GADGETRON_IMAGE_SCALE_RATIO, (double)(1)); - cm3->getObjectPtr()->set(GADGETRON_IMAGE_WINDOWCENTER, (long)(200)); - cm3->getObjectPtr()->set(GADGETRON_IMAGE_WINDOWWIDTH, (long)(400)); - - cm1->getObjectPtr()->matrix_size[0] = (uint16_t)plotIm.get_size(0); - cm1->getObjectPtr()->matrix_size[1] = (uint16_t)plotIm.get_size(1); - cm1->getObjectPtr()->matrix_size[2] = 1; - cm1->getObjectPtr()->channels = 1; - - // make sure pixel is squared in size - float dx = cm1->getObjectPtr()->field_of_view[0] / cm1->getObjectPtr()->matrix_size[0]; - cm1->getObjectPtr()->field_of_view[1] = dx * cm1->getObjectPtr()->matrix_size[1]; - - try - { - cm2->getObjectPtr()->create(img_dims); - } - catch (...) - { - GDEBUG("Unable to allocate new image\n"); - cm1->release(); - return false; - } - - Gadgetron::real_to_complex(plotIm, *cm2->getObjectPtr()); - - // send out the images - if (this->next()->putq(cm1) < 0) - { - return false; - } - } - } - else - { - GDEBUG("Stored noise dependency is NOT found : %s\n", full_name_stored_noise_dependency_.c_str()); - } - } - else - { - GDEBUG("There is no noise stored ... \n"); - } - - return GADGET_OK; -} - -GADGET_FACTORY_DECLARE(NoiseCovariancePlottingGadget) - -} // namespace Gadgetron diff --git a/gadgets/plplot/NoiseCovariancePlottingGadget.h b/gadgets/plplot/NoiseCovariancePlottingGadget.h deleted file mode 100644 index 2b35a8671..000000000 --- a/gadgets/plplot/NoiseCovariancePlottingGadget.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "Gadget.h" -#include "hoNDArray.h" -#include "GadgetronTimer.h" - -#include -#include -#include -#include - -namespace Gadgetron { - - class NoiseCovariancePlottingGadget : public Gadget2 > > - { - public: - typedef Gadget2 > > BaseClass; - - NoiseCovariancePlottingGadget(); - virtual ~NoiseCovariancePlottingGadget(); - - virtual int close(unsigned long flags); - - protected: - - GADGET_PROPERTY(noise_dependency_prefix, std::string, "Prefix of noise dependency file", "GadgetronNoiseCovarianceMatrix"); - GADGET_PROPERTY(xlabel, std::string, "Label for x axis", "Channel"); - GADGET_PROPERTY(ylabel, std::string, "Label for y axis", "Noise Standard Deviation"); - GADGET_PROPERTY(title, std::string, "Label for y axis", "Gadgetron, Noise STD Plot"); - GADGET_PROPERTY(xsize, int, "Noise variane plot, x size", 2048); - GADGET_PROPERTY(ysize, int, "Noise variane plot, y size", 2048); - GADGET_PROPERTY(series_num, int, "Noise plot image sereis number", 10000); - - bool noise_decorrelation_calculated_; - hoNDArray< std::complex > noise_covariance_matrixf_; - - float noise_dwell_time_us_; - bool noiseCovarianceLoaded_; - - std::string noise_dependency_folder_; - std::string noise_dependency_prefix_; - std::string measurement_id_; - std::string measurement_id_of_noise_dependency_; - std::string full_name_stored_noise_dependency_; - - virtual int process_config(ACE_Message_Block* mb); - - virtual int process(GadgetContainerMessage* m1, - GadgetContainerMessage< hoNDArray< std::complex > >* m2); - - std::string generateNoiseDependencyFilename(const std::string& measurement_id); - std::string generateMeasurementIdOfNoiseDependency(const std::string& noise_id); - - bool loadNoiseCovariance(); - void computeNoisePrewhitener(); - - ISMRMRD::IsmrmrdHeader current_ismrmrd_header_; - ISMRMRD::IsmrmrdHeader noise_ismrmrd_header_; - - ISMRMRD::ImageHeader curr_image_header_; - }; -} diff --git a/gadgets/python/CMakeLists.txt b/gadgets/python/CMakeLists.txt deleted file mode 100644 index 5f77d9c94..000000000 --- a/gadgets/python/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ - -set(pingvin_legacy_python_config_files - legacy/config/pseudoreplica.xml - legacy/config/python_buckets.xml - legacy/config/python_short.xml - legacy/config/python_image_array_recon.xml - legacy/config/python_passthrough.xml - legacy/config/python_short.xml) - -set(pingvin_legacy_python_gadgets_files - legacy/gadgets/accumulate_and_recon.py - legacy/gadgets/bucket_recon.py - legacy/gadgets/image_array_recon.py - legacy/gadgets/image_array_recon_rtcine_plotting.py - legacy/gadgets/passthrough.py - legacy/gadgets/passthrough_array_image.py - legacy/gadgets/pseudoreplicagather.py - legacy/gadgets/remove_2x_oversampling.py - legacy/gadgets/rms_coil_combine.py) - -source_group(config FILES ${pingvin_legacy_python_config_files}) -source_group(gadgets FILES ${pingvin_legacy_python_gadgets_files}) - - -set(pingvin_python_config_files - config/Generic_Cartesian_Grappa_RealTimeCine_Python.xml) - -install(FILES ${pingvin_python_config_files} DESTINATION ${PINGVIN_INSTALL_CONFIG_PATH} COMPONENT main) \ No newline at end of file diff --git a/gadgets/python/config/Generic_Cartesian_Grappa_RealTimeCine_Python.xml b/gadgets/python/config/Generic_Cartesian_Grappa_RealTimeCine_Python.xml deleted file mode 100644 index eb5673131..000000000 --- a/gadgets/python/config/Generic_Cartesian_Grappa_RealTimeCine_Python.xml +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionslice - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionphase - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaystrue - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosetrue - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres-1 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressiontrue - downstream_coil_compression_thres0.002 - downstream_coil_compression_num_modesKept0 - - - debug_folder - perform_timingtrue - verbosetrue - - - send_out_gfactortrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingPOCSGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_POCS_iters6 - partial_fourier_POCS_thres0.01 - partial_fourier_POCS_transitBand24 - partial_fourier_POCS_transitBand_E216 - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - PythonImageArray - pingvin_python - PythonGadget - python_moduleimage_array_recon_rtcine_plotting - python_classImageArrayReconRTCinePlotting - debug_folder - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/python/legacy/config/pseudoreplica.xml b/gadgets/python/legacy/config/pseudoreplica.xml deleted file mode 100644 index 900ad7b1c..000000000 --- a/gadgets/python/legacy/config/pseudoreplica.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - NoiseAdjust - pingvin_mricore - NoiseAdjustGadget - - - - PCA - pingvin_mricore - PCACoilGadget - - - - CoilReduction - pingvin_mricore - CoilReductionGadget - coils_out16 - - - - RemoveROOversampling - pingvin_mricore - RemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - trigger_dimension - repetition - - - sorting_dimension - slice - - - - - Buff - pingvin_mricore - BucketToBufferGadget - - N_dimension - - - - S_dimension - - - - split_slices - true - - - - PseudoReplicatorGadget - pingvin_debugging - PseudoReplicatorGadget - - repetitions - 100 - - - - - SimpleRecon - pingvin_mricore - SimpleReconGadget - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - PseudoReplicaGatherPython - pingvin_python - PythonGadget - python_module pseudoreplicagather - python_class PseudoreplicaGather - - repetitions - 100 - - - - diff --git a/gadgets/python/legacy/config/python_buckets.xml b/gadgets/python/legacy/config/python_buckets.xml deleted file mode 100644 index 043deeaeb..000000000 --- a/gadgets/python/legacy/config/python_buckets.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - RemoveROOversampling - pingvin_mricore - RemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - trigger_dimension - repetition - - - - - Buff - pingvin_mricore - BucketToBufferGadget - - split_slices - true - - - - - PassthroughPython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module passthrough - python_class Passthrough - - - - AccReconPython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module bucket_recon - python_class BucketRecon - - - - CoilCombinePython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module rms_coil_combine - python_class RMSCoilCombine - - - - Extract - pingvin_mricore - ExtractGadget - - - \ No newline at end of file diff --git a/gadgets/python/legacy/config/python_image_array_recon.xml b/gadgets/python/legacy/config/python_image_array_recon.xml deleted file mode 100644 index c8d9d3760..000000000 --- a/gadgets/python/legacy/config/python_image_array_recon.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - RemoveROOversampling - pingvin_mricore - RemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - - trigger_dimension - repetition - - - sorting_dimension - slice - - - - - Buff - pingvin_mricore - BucketToBufferGadget - - N_dimension - - - - S_dimension - - - - split_slices - true - - - - - SimpleRecon - pingvin_mricore - SimpleReconGadget - - - - PythonImageArray - pingvin_python - PythonGadget - python_moduleimage_array_recon - python_classImageArrayRecon - - - - Extract - pingvin_mricore - ExtractGadget - - - \ No newline at end of file diff --git a/gadgets/python/legacy/config/python_passthrough.xml b/gadgets/python/legacy/config/python_passthrough.xml deleted file mode 100644 index cbcc59289..000000000 --- a/gadgets/python/legacy/config/python_passthrough.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - NoiseAdjustpingvin_mricoreNoiseAdjustGadget - - - AsymmetricEchopingvin_mricoreAsymmetricEchoAdjustROGadget - - - RemoveROOversamplingpingvin_mricoreRemoveROOversamplingGadget - - - - AccTrig - pingvin_mricore - AcquisitionAccumulateTriggerGadget - trigger_dimensionrepetition - sorting_dimension - - - - BucketToBuffer - pingvin_mricore - BucketToBufferGadget - N_dimensionrepetition - S_dimensionset - split_slicestrue - ignore_segmenttrue - - - - PassthroughPython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module passthrough - python_class Passthrough - - - - - PrepRef - pingvin_mricore - GenericReconCartesianReferencePrepGadget - - - debug_folder - perform_timingtrue - verbosetrue - - - average_all_ref_Ntrue - - average_all_ref_Sfalse - - prepare_ref_alwaysfalse - - - - - CoilCompression - pingvin_mricore - GenericReconEigenChannelGadget - - - debug_folder - perform_timingtrue - verbosetrue - - average_all_ref_Ntrue - average_all_ref_Strue - - - upstream_coil_compressiontrue - upstream_coil_compression_thres-1 - upstream_coil_compression_num_modesKept0 - - - - - Recon - pingvin_mricore - GenericReconCartesianGrappaGadget - - - image_series0 - - - coil_map_algorithmInati - - - downstream_coil_compressiontrue - downstream_coil_compression_thres0.002 - downstream_coil_compression_num_modesKept0 - - - debug_folder - perform_timingtrue - verbosetrue - - - send_out_gfactortrue - - - - - PartialFourierHandling - pingvin_mricore - GenericReconPartialFourierHandlingFilterGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - partial_fourier_filter_RO_width0.15 - partial_fourier_filter_E1_width0.15 - partial_fourier_filter_E2_width0.15 - partial_fourier_filter_densityCompfalse - - - - - KSpaceFilter - pingvin_mricore - GenericReconKSpaceFilteringGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - skip_processing_meta_fieldSkip_processing_after_recon - - - filterROGaussian - filterRO_sigma1.0 - filterRO_width0.15 - - filterE1Gaussian - filterE1_sigma1.0 - filterE1_width0.15 - - filterE2Gaussian - filterE2_sigma1.0 - filterE2_width0.15 - - - - - FOVAdjustment - pingvin_mricore - GenericReconFieldOfViewAdjustmentGadget - - - debug_folder - perform_timingfalse - verbosefalse - - - - - Scaling - pingvin_mricore - GenericReconImageArrayScalingGadget - - - perform_timingfalse - verbosefalse - - min_intensity_value64 - max_intensity_value4095 - scalingFactor10.0 - use_constant_scalingFactortrue - auto_scaling_only_oncetrue - scalingFactor_dedicated100.0 - - - - - ImageArraySplit - pingvin_mricore - ImageArraySplitGadget - - - - ArrayImagePassthroughPython - pingvin_python - PythonGadget - python_path/home/myuser/scripts/python - python_modulepassthrough_array_image - python_classArrayImagePassThrough - - - - - ComplexToFloatAttrib - pingvin_mricore - ComplexToFloatGadget - - - - FloatToShortAttrib - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/python/legacy/config/python_short.xml b/gadgets/python/legacy/config/python_short.xml deleted file mode 100644 index 7d5b1c5c8..000000000 --- a/gadgets/python/legacy/config/python_short.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - RemoveOversamplingPython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module remove_2x_oversampling - python_class Remove2xOversampling - - - - AccReconPython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module accumulate_and_recon - python_class AccumulateAndRecon - - - - CoilCombinePython - pingvin_python - PythonGadget - python_path /home/myuser/scripts/python - python_module rms_coil_combine - python_class RMSCoilCombine - - - - Extract - pingvin_mricore - ExtractGadget - - - - Autoscale - pingvin_mricore - AutoScaleGadget - - - - FloatToShort - pingvin_mricore - FloatToUShortGadget - - - diff --git a/gadgets/python/legacy/gadgets/accumulate_and_recon.py b/gadgets/python/legacy/gadgets/accumulate_and_recon.py deleted file mode 100644 index 7e5c5528f..000000000 --- a/gadgets/python/legacy/gadgets/accumulate_and_recon.py +++ /dev/null @@ -1,79 +0,0 @@ -import numpy as np -import ismrmrd -import ismrmrd.xsd - -from gadgetron import Gadget -from gadgetron.util.cfft import cifftn - - -class AccumulateAndRecon(Gadget): - - def __init__(self, next_gadget=None): - Gadget.__init__(self, next_gadget) - self.myBuffer = None - self.myCounter = 1 - self.mySeries = 1 - self.header = None - self.enc = None - - def process_config(self, conf): - self.header = ismrmrd.xsd.CreateFromDocument(conf) - self.enc = self.header.encoding[0] - - def process(self, acq, data, *args): - if self.myBuffer is None: - channels = acq.active_channels - if self.enc.encodingLimits.slice != None: - nslices = self.enc.encodingLimits.slice.maximum + 1 - else: - nslices = 1 - eNz = self.enc.encodedSpace.matrixSize.z - eNy = self.enc.encodedSpace.matrixSize.y - eNx = self.enc.encodedSpace.matrixSize.x - - self.myBuffer = np.zeros(( int(eNx/2),eNy,eNz,nslices,channels),dtype=np.complex64) - - line_offset = self.enc.encodedSpace.matrixSize.y/2 - self.enc.encodingLimits.kspace_encoding_step_1.center - self.myBuffer[:,int(acq.idx.kspace_encode_step_1+line_offset), int(acq.idx.kspace_encode_step_2), int(acq.idx.slice),:] = data - - if (acq.flags & (1<<7)): #Is this the last scan in slice - image = cifftn(self.myBuffer, axes=(0, 1, 2)) - image = image * np.product(image.shape)*100 #Scaling for the scanner - #Create a new image header and transfer value - img_head = ismrmrd.ImageHeader() - img_head.version = 1 - img_head.measurement_uid = acq.measurement_uid - img_head.field_of_view = ( - self.enc.reconSpace.fieldOfView_mm.x, - self.enc.reconSpace.fieldOfView_mm.y, - self.enc.reconSpace.fieldOfView_mm.z - ) - img_head.channels = acq.active_channels - img_head.matrix_size[0] = self.myBuffer.shape[0] - img_head.matrix_size[1] = self.myBuffer.shape[1] - img_head.matrix_size[2] = self.myBuffer.shape[2] - img_head.position = acq.position - img_head.read_dir = acq.read_dir - img_head.phase_dir = acq.phase_dir - img_head.slice_dir = acq.slice_dir - img_head.patient_table_position = acq.patient_table_position - img_head.average = acq.idx.average - img_head.slice = acq.idx.slice - img_head.contrast = acq.idx.contrast - img_head.phase = acq.idx.phase - img_head.repetition = acq.idx.repetition - img_head.set = acq.idx.set - img_head.acquisition_time_stamp = acq.acquisition_time_stamp - img_head.physiology_time_stamp = acq.physiology_time_stamp - img_head.image_index = self.myCounter - img_head.image_series_index = self.mySeries - img_head.data_type = ismrmrd.DATATYPE_CXFLOAT - self.myCounter += 1 - if self.myCounter > 5: - self.mySeries += 1 - self.myCounter = 1 - - #Return image to Gadgetron - self.put_next(img_head, image.astype('complex64'), *args) - - return 0 #Everything OK diff --git a/gadgets/python/legacy/gadgets/bucket_recon.py b/gadgets/python/legacy/gadgets/bucket_recon.py deleted file mode 100644 index ba93bbd2c..000000000 --- a/gadgets/python/legacy/gadgets/bucket_recon.py +++ /dev/null @@ -1,67 +0,0 @@ -import itertools -import numpy as np -import sys - -from gadgetron import Gadget -from gadgetron.util.cfft import cifftn - -import ismrmrd -import ismrmrd.xsd - - - -class BucketRecon(Gadget): - def __init__(self, next_gadget=None): - Gadget.__init__(self,next_gadget) - self.header = None - self.enc = None - - self.image_indices = itertools.count(1) - - def process_config(self, conf): - self.header = ismrmrd.xsd.CreateFromDocument(conf) - self.enc = self.header.encoding[0] - - def process(self, recondata): - print(np.shape(recondata[0].data.data), file=sys.stderr) - - image = cifftn(recondata[0].data.data, axes=(0, 1, 2)) - image = np.reshape(image,(image.shape[0],image.shape[1],image.shape[2],image.shape[3])) - - #Create a new image header and transfer value - acq = np.ravel(recondata[0].data.headers)[0] - - img_head = ismrmrd.ImageHeader() - img_head.version = 1 - img_head.measurement_uid = acq.measurement_uid - img_head.channels = acq.active_channels - img_head.slice = acq.idx.slice - img_head.matrix_size = (image.shape[0],image.shape[1],image.shape[2]) - img_head.field_of_view = ( - self.enc.reconSpace.fieldOfView_mm.x, - self.enc.reconSpace.fieldOfView_mm.y, - self.enc.reconSpace.fieldOfView_mm.z - ) - img_head.position = acq.position - img_head.read_dir = acq.read_dir - img_head.phase_dir = acq.phase_dir - img_head.slice_dir = acq.slice_dir - img_head.patient_table_position = acq.patient_table_position - img_head.acquisition_time_stamp = acq.acquisition_time_stamp - img_head.average = acq.idx.average - img_head.slice = acq.idx.slice - img_head.contrast = acq.idx.contrast - img_head.phase = acq.idx.phase - img_head.repetition = acq.idx.repetition - img_head.set = acq.idx.set - img_head.image_index = next(self.image_indices) - img_head.image_series_index = 0 - img_head.data_type = ismrmrd.DATATYPE_CXFLOAT - - #Return image to Gadgetron - self.put_next(img_head,image) - print(f"Slice {img_head.slice}", file=sys.stderr) - print("----------------------------------------------", file=sys.stderr) - return 0 - #print "Returning to Gadgetron" - diff --git a/gadgets/python/legacy/gadgets/image_array_recon.py b/gadgets/python/legacy/gadgets/image_array_recon.py deleted file mode 100644 index 73ad9a117..000000000 --- a/gadgets/python/legacy/gadgets/image_array_recon.py +++ /dev/null @@ -1,86 +0,0 @@ -import os -import pickle -import platform -import sys - -import ismrmrd -import ismrmrd.xsd - -from gadgetron import Gadget, IsmrmrdImageArray - -class ImageArrayRecon(Gadget): - - def process_config(self, cfg): - print("ImageArrayRecon, process config ... ", file=sys.stderr) - self.header = ismrmrd.xsd.CreateFromDocument(cfg) - - # first encoding space - self.enc = self.header.encoding[0] - - #Parallel imaging factor - self.acc_factor = self.enc.parallelImaging.accelerationFactor.kspace_encoding_step_1 - self.slc = self.enc.encodingLimits.slice.maximum+1 - - self.array_data = IsmrmrdImageArray() - - try: - self.debug_folder = self.params["debug_folder"] - - if (len(self.debug_folder)==0): - if platform.system() == "Windows": - self.debug_folder = "C:/temp/gadgetron" - else: - self.debug_folder = "/tmp/gadgetron" - except: - self.debug_folder = None - - self.num_processed_ = 0 - - print(f"ImageArrayRecon, maximal number of slice {self.slc}", file=sys.stderr) - print(f"ImageArrayRecon, find debug folder {self.debug_folder}", file=sys.stderr) - - def process(self, array_data): - - ndim = array_data.data.shape - - RO = ndim[0] - E1 = ndim[1] - E2 = ndim[2] - CHA = ndim[3] - PHS = ndim[4] - S = ndim[5] - SLC = ndim[6] - - print(f"\nImageArrayRecon, receiving image array, {ndim}", file=sys.stderr) - - if (self.debug_folder is not None): - save_file = os.path.join(self.debug_folder, "image_array"+str(self.num_processed_)+".dat") - with open(save_file, "wb") as f: - pickle.dump(array_data, f, pickle.HIGHEST_PROTOCOL) - print(f"Save incoming array data to {save_file}", file=sys.stderr) - - # self.put_next(array_data) - - print("ImageArrayRecon, parse meta ... ", file=sys.stderr) - mt = list() - for x in array_data.meta: - curr_meta = ismrmrd.Meta.deserialize(x) - mt.append(curr_meta) - - print(f"ImageArrayRecon, convert {len(mt)} meta containers ... ", file=sys.stderr) - - if array_data.waveform is not None: - print(f"ImageArrayRecon, receive %d waveforms ... {len(array_data.waveform)}", file=sys.stderr) - print(f"ImageArrayRecon, receive waveforms {array_data.waveform}", file=sys.stderr) - - if array_data.acq_headers is not None: - print(f"ImageArrayRecon, receive acq headers ... {array_data.acq_headers.shape}", file=sys.stderr) - - for slc in range(0,SLC): - for s in range(0,S): - for phs in range(0,PHS): - print(f"send out image {phs}-{s}-{slc}", file=sys.stderr) - a = array_data.data[:,:,:,:,phs,s,slc] - self.put_next(array_data.headers[phs,s,slc], a) - - return 0 diff --git a/gadgets/python/legacy/gadgets/image_array_recon_rtcine_plotting.py b/gadgets/python/legacy/gadgets/image_array_recon_rtcine_plotting.py deleted file mode 100644 index 53f2f8808..000000000 --- a/gadgets/python/legacy/gadgets/image_array_recon_rtcine_plotting.py +++ /dev/null @@ -1,155 +0,0 @@ -import os -import sys -import pickle -import platform - -import ismrmrd -import ismrmrd.xsd -import numpy as np - -from gadgetron import Gadget, IsmrmrdImageArray - -class ImageArrayReconRTCinePlotting(Gadget): - - def process_config(self, cfg): - print("ImageArrayReconRTCinePlotting, process config ... ", file=sys.stderr) - self.header = ismrmrd.xsd.CreateFromDocument(cfg) - - # first encoding space - self.enc = self.header.encoding[0] - - #Parallel imaging factor - self.acc_factor = self.enc.parallelImaging.accelerationFactor.kspace_encoding_step_1 - self.slc = self.enc.encodingLimits.slice.maximum+1 - - self.data = None - self.headers = None - self.waveforms = list() - self.acq_headers = None - self.meta = list() - - self.array_data = IsmrmrdImageArray() - - try: - self.debug_folder = self.params["debug_folder"] - - if (len(self.debug_folder)==0): - if platform.system() == "Windows": - self.debug_folder = "C:/temp/gadgetron" - else: - self.debug_folder = "/tmp/gadgetron" - except: - self.debug_folder = None - - self.num_processed_ = 0 - - print(f"ImageArrayReconRTCinePlotting, maximal number of slice {self.slc}", file=sys.stderr) - print(f"ImageArrayReconRTCinePlotting, find debug folder {self.debug_folder}", file=sys.stderr) - - def process(self, array_data): - - ndim = array_data.data.shape - - RO = ndim[0] - E1 = ndim[1] - E2 = ndim[2] - CHA = ndim[3] - PHS = ndim[4] - S = ndim[5] - SLC = ndim[6] - - curr_slc = array_data.headers[0,0,0].slice - print(f"\ImageArrayReconRTCinePlotting, receiving image array, {ndim} for slice {curr_slc}", file=sys.stderr) - - print("ImageArrayReconRTCinePlotting, parse meta ... ", file=sys.stderr) - mt = list() - for x in array_data.meta: - curr_meta = ismrmrd.Meta.deserialize(x) - mt.append(curr_meta) - - print(f"ImageArrayReconRTCinePlotting, convert {len(mt)} meta containers ... ", file=sys.stderr) - - buffer_for_plotting = True - if array_data.waveform is not None: - print(f"ImageArrayReconRTCinePlotting, receive {len(array_data.waveform)} waveforms ... ", file=sys.stderr) - else: - buffer_for_plotting = False - - if array_data.acq_headers is not None: - print(f"ImageArrayReconRTCinePlotting, receive acq headers ... {array_data.acq_headers.shape}", file=sys.stderr) - else: - buffer_for_plotting = False - print("Will not buffer for plotting ... ", file=sys.stderr) - - if buffer_for_plotting: - if (self.num_processed_==0): - # allocate data buffer - self.data = np.zeros([RO, E1, E2, CHA, PHS, S, self.slc]) - print(f"Create data buffer {self.data.shape}", file=sys.stderr) - self.headers = array_data.headers - self.acq_headers = array_data.acq_headers - print(f"Create headers buffer {self.headers.shape}", file=sys.stderr) - print(f"Create acq_headers buffer {self.acq_headers.shape}", file=sys.stderr) - - self.data[:,:,:,:,:,:,curr_slc] = array_data.data.reshape([RO, E1, E2, CHA, PHS, S]) - self.waveforms.extend(array_data.waveform) - self.meta.extend(array_data.meta) - - if (self.num_processed_>0): - print(f"Incoming headers {array_data.headers.shape}", file=sys.stderr) - self.headers = np.append(self.headers, array_data.headers, axis=2) - print(f"Incoming acq headers {array_data.acq_headers.shape}", file=sys.stderr) - self.acq_headers = np.append(self.acq_headers, array_data.acq_headers, axis=3) - - if (self.debug_folder is not None): - save_file = os.path.join(self.debug_folder, "image_array"+str(self.num_processed_)+".dat") - with open(save_file, "wb") as f: - pickle.dump(array_data, f, pickle.HIGHEST_PROTOCOL) - print(f"Save incoming array data to {save_file}", file=sys.stderr) - - # send out images to next gadget - for slc in range(0,SLC): - for s in range(0,S): - for phs in range(0,PHS): - print("send out image %d-%d-%d" % (phs, s, slc), file=sys.stderr) - a = array_data.data[:,:,:,:,phs,s,slc] - print(a.shape, file=sys.stderr) - self.put_next(array_data.headers[phs,s,slc], a, array_data.meta[phs+s*PHS + slc*S*PHS]) - - if buffer_for_plotting: - self.num_processed_+=1 - - if(self.num_processed_==self.slc): - print("ImageArrayReconRTCinePlotting, receive all slices ... ", file=sys.stderr) - - # save data - save_file = os.path.join(self.debug_folder, "image_array_all_data.dat") - with open(save_file, "wb") as f: - pickle.dump(self.data, f) - print(f"Save incoming array data to {save_file}", file=sys.stderr) - f.close() - - save_file = os.path.join(self.debug_folder, "image_array_all_headers.dat") - with open(save_file, "wb") as f: - pickle.dump(self.headers, f) - print(f"Save incoming array headers to {save_file}", file=sys.stderr) - f.close() - - save_file = os.path.join(self.debug_folder, "image_array_all_waveforms.dat") - with open(save_file, "wb") as f: - pickle.dump(self.waveforms, f) - print(f"Save incoming array waveforms to {save_file}", file=sys.stderr) - f.close() - - save_file = os.path.join(self.debug_folder, "image_array_all_acq_headers.dat") - with open(save_file, "wb") as f: - pickle.dump(self.acq_headers, f) - print(f"Save incoming array acq_headers to {save_file}", file=sys.stderr) - f.close() - save_file = os.path.join(self.debug_folder, "image_array_all_acq_meta.dat") - with open(save_file, "wb") as f: - pickle.dump(self.meta, f) - print(f"Save incoming array meta to {save_file}", file=sys.stderr) - f.close() - - return 0 diff --git a/gadgets/python/legacy/gadgets/passthrough.py b/gadgets/python/legacy/gadgets/passthrough.py deleted file mode 100644 index b7ce55dd8..000000000 --- a/gadgets/python/legacy/gadgets/passthrough.py +++ /dev/null @@ -1,13 +0,0 @@ -from gadgetron import Gadget -class Passthrough(Gadget): - def __init__(self, next_gadget=None): - Gadget.__init__(self,next_gadget) - - def process_config(self, conf): - pass - - def process(self, recondata,*args): - #Return image to Gadgetron - self.put_next(recondata) - return 0 - diff --git a/gadgets/python/legacy/gadgets/passthrough_array_image.py b/gadgets/python/legacy/gadgets/passthrough_array_image.py deleted file mode 100644 index 0665604bf..000000000 --- a/gadgets/python/legacy/gadgets/passthrough_array_image.py +++ /dev/null @@ -1,32 +0,0 @@ -import sys - -from gadgetron import Gadget - - - -class ArrayImagePassThrough(Gadget): - def __init__(self,next_gadget=None): - super(ArrayImagePassThrough,self).__init__(next_gadget=next_gadget) - self.counter = [] - - def process_config(self, cfg): - self.images = [] - self.headers = [] - self.metas = [] - self.counter = 0 - - def process(self, header, image, metadata=None): - - self.images.append(image) - self.headers.append(header) - if metadata is not None: - self.metas.append(metadata) - print(metadata, file=sys.stderr) - - #Send the combined image and the modified header and metadata - if metadata is not None: - self.put_next(header, image, metadata) - else: - self.put_next(header, image) - - return 0 diff --git a/gadgets/python/legacy/gadgets/pseudoreplicagather.py b/gadgets/python/legacy/gadgets/pseudoreplicagather.py deleted file mode 100644 index f51cf6393..000000000 --- a/gadgets/python/legacy/gadgets/pseudoreplicagather.py +++ /dev/null @@ -1,56 +0,0 @@ -import sys - -import ismrmrd -import ismrmrd.xsd -from numpy import * - -from gadgetron import Gadget - - - -def calcPseudoreplica(original, pseudoreplicas): - stdImg = std(pseudoreplicas,axis=pseudoreplicas.ndim-1) - return stdImg - -class PseudoreplicaGather(Gadget): - def __init__(self, next_gadget=None): - Gadget.__init__(self,next_gadget) - self.imageBuffer = None - self.counter = 0 - self.header = None - self.enc = None - self.original = None - - def process_config(self, conf): - #self.header = ismrmrd.xsd.CreateFromDocument(conf) - #self.enc = self.header.encoding[0] - print(self.params, file=sys.stderr) - self.repetitions = int(self.params["repetitions"]) - - def process(self, header, img,*args): - if self.imageBuffer is None: - s = shape(img) - s2 = s + (self.repetitions,) - self.imageBuffer = zeros(s2,dtype=complex64) - - if self.counter == 0: #First image is without added noise. - self.original = img - else: - self.imageBuffer[...,self.counter - 1] = img - - print(f"Counter: {self.counter} Repetitions: {self.repetitions}") - if (self.counter == self.repetitions): - img_head = header - img_head.data_type = ismrmrd.DATATYPE_FLOAT - pseudoreplica = calcPseudoreplica(self.original,self.imageBuffer) - #Return image to Gadgetron - self.counter = 0 - self.imageBuffer = None - self.original = None - print(f"Putting image on stream", file=sys.stderr) - self.put_next(img_head,pseudoreplica.astype('float32'),*args) - else: - self.counter += 1 - - #print "Returning to Gadgetron" - return 0 #Everything OK diff --git a/gadgets/python/legacy/gadgets/remove_2x_oversampling.py b/gadgets/python/legacy/gadgets/remove_2x_oversampling.py deleted file mode 100644 index 33dc8f693..000000000 --- a/gadgets/python/legacy/gadgets/remove_2x_oversampling.py +++ /dev/null @@ -1,18 +0,0 @@ - -from gadgetron import Gadget -from gadgetron.util.cfft import cfftn, cifftn - - -class Remove2xOversampling(Gadget): - - def process(self, acq, data): - orig_size = list(data.shape) - data2 = data.reshape([data.shape[0], int(data.size/data.shape[0])]) - new_length = data2.shape[0] // 2 - data2 = cfftn(cifftn(data2, axes=[0])[(0+(new_length // 2)):(new_length+(new_length // 2)), :], axes=[0]) - orig_size[0] = new_length - data2.reshape(tuple(orig_size)) - acq.samples = new_length - - self.put_next(acq, data2) - return 0 diff --git a/gadgets/python/legacy/gadgets/rms_coil_combine.py b/gadgets/python/legacy/gadgets/rms_coil_combine.py deleted file mode 100644 index 57d607bac..000000000 --- a/gadgets/python/legacy/gadgets/rms_coil_combine.py +++ /dev/null @@ -1,12 +0,0 @@ -import numpy as np -from gadgetron import Gadget - - -class RMSCoilCombine(Gadget): - - def process(self, h, im): - combined_image = np.sqrt(np.sum(np.square(np.abs(im)), axis=len(im.shape) - 1)) - # print("RMS coil", im.shape, combined_image.shape) - h.channels = 1 - self.put_next(h, combined_image.astype('complex64')) - return 0 diff --git a/test/e2e/conftest.py b/test/e2e/conftest.py index 0f68c5edc..4a144afcc 100644 --- a/test/e2e/conftest.py +++ b/test/e2e/conftest.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import pytest import os diff --git a/test/integration/README.md b/test/integration/README.md new file mode 100644 index 000000000..71091384e --- /dev/null +++ b/test/integration/README.md @@ -0,0 +1,9 @@ +# Integration Test Conversion + +This directory is now considered "legacy", but the test cases remain here until we have a proper "Siemens -> MRDv2" converter. + +For now, if the MRDv2 model changes, or Siemens test data is added/updated, we can use the `convert_test_data.py` tool in this directory. + +The converter tool reads each of the legacy "integration" test cases (`./cases/`) and test data (`./data`) and generates new end-to-end tests in `test/e2e/cases/`. + +Once we have a proper "Siemens -> MRDv2" converter, we can skip the intermediate ISMRMRD v1 conversion and remove this directory. \ No newline at end of file diff --git a/test/integration/bart_cases/bart.cfg b/test/integration/bart_cases/bart.cfg deleted file mode 100644 index dfb2a41ff..000000000 --- a/test/integration/bart_cases/bart.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[SIEMENS] -data_file=bart/meas_MID00168_FID39823_R3_RT_Cine_res160_46ms_NL_BART_Proto1.dat -dependency_measurement=1 -data_measurement=2 - -[CLIENT] -configuration=BART_Recon.xml - -[TEST] -reference_file=bart/ref_20180531.h5 -reference_dataset=BART_Recon.xml/image_1/data -output_dataset=BART_Recon.xml/image_1/data -value_comparison_threshold=1e-3 -scale_comparison_threshold=1e-3 - -[REQUIREMENTS] -system_memory=8092 diff --git a/toolboxes/CMakeLists.txt b/toolboxes/CMakeLists.txt index 1fbd162e4..5de341162 100644 --- a/toolboxes/CMakeLists.txt +++ b/toolboxes/CMakeLists.txt @@ -12,7 +12,6 @@ add_subdirectory(cmr) add_subdirectory(mri_image) add_subdirectory(klt) -add_subdirectory(fatwater) add_subdirectory(deblur) add_subdirectory(nfft) add_subdirectory(dwt) @@ -24,16 +23,11 @@ add_subdirectory(pattern_recognition) add_subdirectory(denoise) add_subdirectory(image_io) -add_subdirectory(T1) if (BUILD_PYTHON_SUPPORT) add_subdirectory(python) endif () -if (ARMADILLO_FOUND AND Boost_FOUND AND PLPLOT_FOUND) - add_subdirectory(plplot) -endif () - if(CUDA_FOUND) # We compile all GPU code into one library to workaround Thrust and Cub using statics in templates # (e.g. https://github.com/NVIDIA/cub/blob/48768e86a40c25d231a6ff1e04107a60016314a7/cub/util_device.cuh#L208) @@ -77,10 +71,6 @@ if(CUDA_FOUND) fft/gpu/cuNDFFT.cpp fft/gpu/cuNDFFT.cu fft/gpu/cuNDFFT.h - mri/hyper/CSI_utils.cu - mri/hyper/CSI_utils.h - mri/hyper/CSIOperator.cpp - mri/hyper/CSIOperator.h mri/pmri/gpu/b1_map_NIH_Souheil.cu mri/pmri/gpu/b1_map.cu mri/pmri/gpu/b1_map.h @@ -143,7 +133,6 @@ if(CUDA_FOUND) ${CMAKE_CURRENT_SOURCE_DIR}/core/gpu ${CMAKE_CURRENT_SOURCE_DIR}/dwt/gpu/ ${CMAKE_CURRENT_SOURCE_DIR}/fft/gpu - ${CMAKE_CURRENT_SOURCE_DIR}/mri/hyper ${CMAKE_CURRENT_SOURCE_DIR}/mri/pmri/gpu ${CMAKE_CURRENT_SOURCE_DIR}/nfft/gpu ${CMAKE_CURRENT_SOURCE_DIR}/operators/gpu @@ -207,8 +196,6 @@ if(CUDA_FOUND) fft/gpu/cuFFTPlan.h fft/gpu/cuFFTPlan.hpp fft/gpu/cuNDFFT.h - mri/hyper/CSI_utils.h - mri/hyper/CSIOperator.h mri/pmri/gpu/b1_map.h mri/pmri/gpu/cuBuffer.h mri/pmri/gpu/cuCartesianSenseOperator.h diff --git a/toolboxes/T1/CMakeLists.txt b/toolboxes/T1/CMakeLists.txt deleted file mode 100644 index 5ab93aee7..000000000 --- a/toolboxes/T1/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ - - - -add_library(pingvin_toolbox_t1 SHARED - t1fit.cpp) - -set_target_properties(pingvin_toolbox_t1 PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_toolbox_t1 - pingvin_toolbox_log - pingvin_toolbox_cpucore - pingvin_toolbox_cpucore_math - pingvin_toolbox_cpu_solver - pingvin_toolbox_demons - pingvin_toolbox_cmr - armadillo - ) -target_include_directories(pingvin_toolbox_t1 - PUBLIC - - $ - $ - ) - -install(TARGETS pingvin_toolbox_t1 - EXPORT pingvin-export - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - - -install(FILES - t1fit.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) diff --git a/toolboxes/T1/t1fit.cpp b/toolboxes/T1/t1fit.cpp deleted file mode 100644 index dd26a1f95..000000000 --- a/toolboxes/T1/t1fit.cpp +++ /dev/null @@ -1,606 +0,0 @@ -#include "t1fit.h" -#include "HybridLM.h" -#include "hoArmadillo.h" -#include "hoNDArray_math.h" -#include - -#include "cmr_motion_correction.h" -#include "demons_registration.h" -#include "hoNDArray_utils.h" -#include "hoNDImage.h" - -namespace { -using namespace Gadgetron; -using namespace Gadgetron::T1; - -template struct T1starResidual_2param { - const std::vector& TI; - const std::vector& measurement; - - void operator()(const arma::Col& params, arma::Col& residual, arma::Mat& jacobian) const { - const auto& T1 = params[0]; - const auto& A = params[1]; - - for (int i = 0; i < residual.n_elem; i++) { - T coeff = T(2) * std::exp(-TI[i] / T1); - residual(i) = measurement[i] - A * (T(1) - coeff); - jacobian(i, 0) = A*TI[i] * coeff / (T1*T1); - jacobian(i, 1) = coeff-1; - } - } -}; - -template struct T1starResidual_3param { - const std::vector& TI; - const std::vector& measurement; - - void operator()(const arma::Col& params, arma::Col& residual, arma::Mat& jacobian) const { - const auto& T1s = params[0]; - const auto& A = params[1]; - const auto& B = params[2]; - - for (int i = 0; i < residual.n_elem; i++) { - T coeff = std::exp(-TI[i] / T1s); - residual(i) = measurement[i] - (A - B * coeff ); - jacobian(i, 0) = B*TI[i]*coeff/(T1s*T1s); - jacobian(i, 1) = -1; - jacobian(i, 2) = coeff; - } - - } -}; - -template struct T1Residual_3param { - const std::vector& TI; - const std::vector& measurement; - - void operator()(const arma::Col& params, arma::Col& residual, arma::Mat& jacobian) const { - const auto& T1 = params[0]; - const auto& A = params[1]; - const auto& B = params[2]; - - const auto T1s = T1/(B/A-1); - - for (int i = 0; i < residual.n_elem; i++) { - T coeff = std::exp(-TI[i]/T1s); - residual(i) = measurement[i] - (A - B * coeff ); - jacobian(i, 0) = B*coeff*TI[i]/(T1s*T1); - jacobian(i, 1) = B*coeff*TI[i]*B/(T1*A*A)-1; - jacobian(i, 2) = (1-B*TI[i]/(T1*A))*coeff; - } - - } -}; - -struct T1_2param_value { - float T1; - float A; -}; - -template T1_2param_value fit_T1_2param_single(const std::vector& TI, const std::vector& data) { - - T A = *std::max_element(data.begin(), data.end()) - *std::min_element(data.begin(), data.end()); - T T1 = 800; - - T1starResidual_2param f{TI, data}; - - Solver::HybridLMSolver solver(data.size(), 2); - arma::Col params{T1, A}; - auto status = solver.solve(f, params); - switch (status) { - case Solver::ReturnStatus::LINEAR_SOLVER_FAILED: - return {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}; - case Solver::ReturnStatus::MAX_ITERATIONS_REACHED: - return {0, 0}; - case Solver::ReturnStatus::SUCCESS: - break; - } - - return {params[0], params[1]}; -} - -struct T1_3param_value { - float T1; - float A; - float B; -}; - -template T1_3param_value fit_T1_3param_single(const std::vector& TI, const std::vector& data) { - - T A = *std::max_element(data.begin(), data.end()); - T B = A - *std::min_element(data.begin(), data.end()); - T T1 = 800; - - T1starResidual_3param f{TI, data}; - - Solver::HybridLMSolver solver(data.size(), 3); - arma::Col params{T1, A, B}; - auto status = solver.solve(f, params); - switch (status) { - case Solver::ReturnStatus::LINEAR_SOLVER_FAILED: - return {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), - std::numeric_limits::quiet_NaN()}; - case Solver::ReturnStatus::MAX_ITERATIONS_REACHED: - return {0,0,0}; - case Solver::ReturnStatus::SUCCESS: - break; - } - return {params[0], params[1], params[2]}; -} - -template -static auto truncated_median( CONTAINER container, size_t truncated_length){ - - auto trunc_median_position = std::end(container) - truncated_length/2 -1 ; - std::nth_element(std::begin(container),trunc_median_position, std::end(container)); - if (truncated_length % 2 == 1) return *trunc_median_position; - - auto trunc_median_position2 = trunc_median_position + 1; - std::nth_element(trunc_median_position,trunc_median_position2,std::end(container)); - return (*trunc_median_position+*trunc_median_position2)/2; -} - -double estimate_t1_standard_deviation(const std::vector& TI, const std::vector& data, double a, double b, - double t1) { - - if (a <= 0 && b <= 0 || b < a ) return 0; - - T1Residual_3param f{TI, data}; - const size_t nparams = 3; - - auto jacobian = arma::Mat(TI.size(), nparams, arma::fill::zeros); - auto residual = arma::Col(TI.size(), arma::fill::zeros); - - arma::Col params = {t1, a, b}; - - f(params, residual, jacobian); - - residual = abs(residual); - - double mad_sd = truncated_median(residual,data.size()-(nparams-1))/0.6745; - - jacobian = jacobian/mad_sd; - arma::Mat hessian = jacobian.t() * jacobian; - arma::Mat covariance; - auto is_valid = arma::inv(covariance,hessian); - if (is_valid) return std::sqrt(covariance(0, 0)); - return 0; - -} -} // namespace - -hoNDArray Gadgetron::T1::calculate_error_map(const T1_3param& params, const hoNDArray& data, - const std::vector& TI) { - const auto& A = params.A; - const auto& B = params.B; - const auto& T1 = params.T1star; - - auto TId = std::vector(TI.begin(),TI.end()); - auto result = hoNDArray(A.dimensions()); -#pragma omp parallel default(shared) - { - std::vector timeseries(TI.size()); -#pragma omp for - for (int y = 0; y < (int)A.get_size(1); y++) { - for (int x = 0; x < (int)A.get_size(0); x++) { - - for (int cha = 0; cha < TI.size(); cha++) { - timeseries[cha] = data(x, y, cha); - } - auto standard_deviation = estimate_t1_standard_deviation(TId, timeseries, A(x, y), B(x, y), T1(x, y)); - result(x, y) = standard_deviation; - } - } - } - return result; -} - -hoNDArray Gadgetron::T1::predict_signal(const T1_2param& params, const std::vector& TI) { - - const auto& [A, T1] = params; - - auto dimensions = A.dimensions(); - dimensions.push_back(TI.size()); - auto result = hoNDArray(dimensions); - for (int cha = 0; cha < (int)TI.size(); cha++) { - for (int y = 0; y < (int)A.get_size(1); y++) { - for (int x = 0; x < (int)A.get_size(0); x++) { - result(x, y, cha) = A(x, y) * (1 - 2 * std::exp(-TI[cha] / T1(x, y))); - } - } - } - - return result; -} - -hoNDArray Gadgetron::T1::predict_signal(const T1_3param& params, const std::vector& TI) { - - const auto& [A, B, T1] = params; - - auto result = hoNDArray(A.dimensions()); - for (int cha = 0; cha < (int)TI.size(); cha++) { - for (int y = 0; y < (int)A.get_size(1); y++) { - for (int x = 0; x < (int)A.get_size(0); x++) { - result(x, y, cha) = A(x, y) - B(x, y) * std::exp(-TI[cha] / T1(x, y)); - } - } - } - - return result; -} - -T1_2param Gadgetron::T1::fit_T1_2param(const hoNDArray& data, const std::vector& TI) { - - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto A = hoNDArray({data.get_size(0), data.get_size(1)}); - auto T1 = A; - -#pragma omp parallel - { - std::vector data_view(TI.size()); -#pragma omp for - for (int y = 0; y < (int)data.get_size(1); y++) { - for (int x = 0; x < (int)data.get_size(0); x++) { - for (int t = 0; t < (int)TI.size(); t++) { - data_view[t] = data(x, y, t); - } - - auto result = fit_T1_2param_single(TI, data_view); - - A(x, y) = result.A; - T1(x, y) = result.T1; - } - } - } - return {A, T1}; -} - -namespace { - -float calculate_residual(const T1_2param_value vals, const std::vector& TI, const std::vector& data) { - float result = 0; - for (int i = 0; i < (int)TI.size(); i++) { - auto diff = data[i] - vals.A * (1 - 2 * std::exp(-TI[i] / vals.T1)); - result += diff * diff; - } - return std::sqrt(result); -} - -float calculate_residual(const T1_3param_value vals, const std::vector& TI, const std::vector& data) { - float result = 0; - for (int i = 0; i < (int)TI.size(); i++) { - auto diff = data[i] - (vals.A - vals.B * std::exp(-TI[i] / vals.T1)); - result += diff * diff; - } - return std::sqrt(result); -} - -} // namespace - -T1_2param Gadgetron::T1::fit_T1_2param(const hoNDArray>& data, const std::vector& TI) { - - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto A = hoNDArray(data.get_size(0), data.get_size(1)); - auto T1 = A; - -#pragma omp parallel - { - std::vector data_view(TI.size()); - std::vector residual(TI.size()); - std::vector A_values(TI.size()); - std::vector T1_values(TI.size()); - -#pragma omp for - for (int y = 0; y < (int)data.get_size(1); y++) { - for (int x = 0; x < (int)data.get_size(0); x++) { - for (int t = 0; t < (int)TI.size(); t++) { - data_view[t] = std::abs(data(x, y, t)); - } - - for (int t = 0; t < (int)TI.size(); t++) { - for (int k = 0; k < t; k++) { - data_view[k] = -std::abs(data_view[k]); - } - auto result = fit_T1_2param_single(TI, data_view); - A_values[t] = result.A; - T1_values[t] = result.T1; - residual[t] = calculate_residual(result, TI, data_view); - } - - auto smallest_residual_index = std::min_element(residual.begin(), residual.end()) - residual.begin(); - A(x, y) = A_values[smallest_residual_index]; - T1(x, y) = T1_values[smallest_residual_index]; - } - } - } - return {A, T1}; -} - -T1_3param Gadgetron::T1::fit_T1_3param(const hoNDArray& data, const std::vector& TI) { - - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto A = hoNDArray({data.get_size(0), data.get_size(1)}); - auto B = hoNDArray({data.get_size(0), data.get_size(1)}); - auto T1 = hoNDArray({data.get_size(0), data.get_size(1)}); - -#pragma omp parallel - { - std::vector data_view(TI.size()); -#pragma omp for - for (int y = 0; y < (int)data.get_size(1); y++) { - for (int x = 0; x < (int)data.get_size(0); x++) { - for (int t = 0; t < (int)TI.size(); t++) { - data_view[t] = data(x, y, t); - } - - auto result = fit_T1_3param_single(TI, data_view); - - A(x, y) = result.A; - B(x, y) = result.B; - T1(x, y) = result.T1; - } - } - } - return {A, B, T1}; -} -T1_3param Gadgetron::T1::fit_T1_3param(const hoNDArray>& data, const std::vector& TI) { - - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto A = hoNDArray(data.get_size(0), data.get_size(1)); - auto B = A; - auto T1 = A; - -#pragma omp parallel - { - std::vector data_view(TI.size()); - std::vector residual(TI.size()); - std::vector A_values(TI.size()); - std::vector B_values(TI.size()); - std::vector T1_values(TI.size()); - -#pragma omp for - for (int y = 0; y < (int)data.get_size(1); y++) { - for (int x = 0; x < (int)data.get_size(0); x++) { - for (int t = 0; t < (int)TI.size(); t++) { - data_view[t] = std::abs(data(x, y, t)); - } - - for (int t = 0; t < (int)TI.size(); t++) { - for (int k = 0; k < t; k++) { - data_view[k] = -std::abs(data_view[k]); - } - auto result = fit_T1_3param_single(TI, data_view); - A_values[t] = result.A; - B_values[t] = result.B; - T1_values[t] = result.T1; - residual[t] = calculate_residual(result, TI, data_view); - } - - auto smallest_residual_index = std::min_element(residual.begin(), residual.end()) - residual.begin(); - A(x, y) = A_values[smallest_residual_index]; - B(x, y) = B_values[smallest_residual_index]; - T1(x, y) = T1_values[smallest_residual_index]; - } - } - } - return {A, B, T1}; -} -hoNDArray Gadgetron::T1::phase_correct(const hoNDArray>& data, - const std::vector& TI) { - - hoNDArray result(data.dimensions()); - auto max_TI_index = std::distance(TI.begin(), std::max_element(TI.begin(), TI.end())); - for (long long y = 0; y < (long long)data.get_size(1); y++) { - for (long long x = 0; x < (long long)data.get_size(0); x++) { - auto reference_phase = std::arg(data(x, y, max_TI_index)); - - for (long long i = 0; i < (long long)data.get_size(2); i++) { - auto val = data(x, y, i); - result(x, y, i) = std::abs(val) * std::polar(1.0f, std::arg(val) - reference_phase).real(); - } - } - } - - return result; -} -namespace { - -hoNDArray> register_groups(const hoNDArray& phase_corrected_data, - const hoNDArray& predicted, - hoNDArray> vector_field, - const registration_params& params) { - using namespace Indexing; - - auto abs_corrected = abs(phase_corrected_data); - auto abs_predicted = abs(predicted); - -#pragma omp parallel for - for (long long cha = 0; cha < (long long)predicted.get_size(2); cha++) { - vector_field(slice, slice, cha) = Registration::diffeomorphic_demons( - abs_corrected(slice, slice, cha), abs_predicted(slice, slice, cha), vector_field(slice, slice, cha), - params.iterations, params.regularization_sigma, params.step_size, params.noise_sigma); - } - - return vector_field; -} - -template -auto deform_groups_internal(const hoNDArray& data, const hoNDArray>& vector_field) { - using namespace Indexing; - assert(data.dimensions_equal(vector_field.dimensions())); - assert(data.dimensions().size() == 3); - - auto output = hoNDArray(data.dimensions()); - for (long long cha = 0; cha < (long long)data.get_size(2); cha++) { - output(slice, slice, cha) = - Registration::deform_image_bspline(data(slice, slice, cha), vector_field(slice, slice, cha)); - } - return output; -} -} // namespace - -hoNDArray> Gadgetron::T1::deform_groups(const hoNDArray>& data, - const hoNDArray>& vector_field) { - return deform_groups_internal(data, vector_field); -} -hoNDArray Gadgetron::T1::deform_groups(const hoNDArray& data, - const hoNDArray>& vector_field) { - return deform_groups_internal(data, vector_field); -} - -hoNDArray> Gadgetron::T1::t1_registration(const hoNDArray>& data, - const std::vector& TI, unsigned int iterations, - registration_params params) { - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto corrected = phase_correct(data, TI); - - auto corrected_orig = corrected; - - auto vector_field = hoNDArray>(data.dimensions()); - vector_field.fill(vector_td(0)); - - return t1_registration(data, TI, std::move(vector_field), iterations, params); -}; - -hoNDArray> Gadgetron::T1::t1_registration(const hoNDArray>& data, - const std::vector& TI, - hoNDArray> vector_field, - unsigned int iterations, registration_params params) { - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - if (data.dimensions() != vector_field.dimensions()) { - throw std::runtime_error("Data and vector field have difference sizes."); - } - - auto corrected = phase_correct(data, TI); - - auto corrected_orig = corrected; - - for (int i = 0; i < iterations; i++) { - auto parameters = fit_T1_2param(corrected, TI); - auto predicted = predict_signal(parameters, TI); - vector_field = register_groups(corrected_orig, predicted, vector_field, params); - auto deformed_data = deform_groups(data, vector_field); - corrected = phase_correct(deformed_data, TI); - } - return vector_field; -}; - -namespace { -auto t1_registration_vfield(const hoNDArray>& data, hoNDArray> vector_field, - const std::vector& TI, unsigned int iterations, registration_params params) { - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto corrected = phase_correct(data, TI); - auto corrected_orig = corrected; - { - auto deformed_data = deform_groups(data, vector_field); - corrected = phase_correct(deformed_data, TI); - } - - for (int i = 0; i < iterations; i++) { - auto parameters = fit_T1_2param(corrected, TI); - auto predicted = predict_signal(parameters, TI); - auto updated_vector_field = register_groups(corrected_orig, predicted, vector_field, params); - vector_field = updated_vector_field; - auto deformed_data = deform_groups(data, vector_field); - corrected = phase_correct(deformed_data, TI); - } - return vector_field; -}; -} // namespace - -hoNDArray> Gadgetron::T1::multi_scale_t1_registration(const hoNDArray>& data, - const std::vector& TI, - unsigned int levels, unsigned int iterations, - registration_params params) { - if (levels <= 1) - return t1_registration(data, TI, iterations, params); - - auto data_pyramid = std::vector{data}; - - for (int i = 0; i < int(levels) - 1; i++) { - data_pyramid.push_back(downsample, 2>(data_pyramid.back())); - } - - auto current_vfield = t1_registration(data_pyramid.back(), TI, iterations, params); - current_vfield = upsample, 2>(current_vfield); - current_vfield *= vector_td(2); - - for (int i = data_pyramid.size() - 2; i > 0; i--) { - current_vfield = t1_registration_vfield(data_pyramid[i], current_vfield, TI, iterations, params); - current_vfield = upsample, 2>(current_vfield); - current_vfield *= vector_td(2); - } - - current_vfield = t1_registration_vfield(data, current_vfield, TI, iterations, params); - return current_vfield; -} - -hoNDArray> Gadgetron::T1::register_groups_CMR(const hoNDArray& phase_corrected_data, - const hoNDArray& predicted, - float hilbert_strength) { - using ImageType = hoNDImage; - using RegType = Gadgetron::hoImageRegContainer2DRegistration; - RegType reg; - - std::vector iters = {32, 64, 100, 100}; // Stolen from MocoSASAH - - perform_moco_pair_wise_frame_2DT(predicted, phase_corrected_data, hilbert_strength, iters, true, false, reg); - - hoNDArray dx; - hoNDArray dy; - reg.deformation_field_[0].to_NDArray(0, dx); - reg.deformation_field_[1].to_NDArray(0, dy); - - hoNDArray> vfield(dx.dimensions()); - - for (int64_t i = 0; i < vfield.size(); i++) { - vfield[i] = vector_td(dx[i], dy[i]); - } - return vfield; -} - -hoNDArray> Gadgetron::T1::t1_moco_cmr(const hoNDArray>& data, - const std::vector& TI, unsigned int iterations) { - - if (data.get_size(2) != TI.size()) { - throw std::runtime_error("Data and TI do not match"); - } - - auto corrected = phase_correct(data, TI); - - auto corrected_orig = abs(corrected); - - auto deformed_data = hoNDArray>{}; - - auto vector_field = hoNDArray>(data.dimensions()); - vector_field.fill(vector_td(0)); - - for (int i = 0; i < iterations; i++) { - auto parameters = fit_T1_2param(corrected, TI); - auto predicted = predict_signal(parameters, TI); - vector_field = register_groups_CMR(corrected_orig, abs(predicted)); - deformed_data = deform_groups(data, vector_field); - corrected = phase_correct(deformed_data, TI); - } - return vector_field; -} diff --git a/toolboxes/T1/t1fit.h b/toolboxes/T1/t1fit.h deleted file mode 100644 index 92790d0f8..000000000 --- a/toolboxes/T1/t1fit.h +++ /dev/null @@ -1,106 +0,0 @@ -// -// Created by dchansen on 3/4/20. -// - -#pragma once - -#include "hoNDArray.h" -namespace Gadgetron::T1 { - -struct T1_2param { - hoNDArray A; - hoNDArray T1; -}; - -struct T1_3param { - hoNDArray A; - hoNDArray B; - hoNDArray T1star; -}; - -/** - * Fits a T1 map using the 2 parameter model - * @param data Data of shape (X,Y,TI) - * @param TI Inversion times - * @return Magnitude (A) and T1 mapping - */ -T1_2param fit_T1_2param(const hoNDArray& data, const std::vector& TI); - -/** - * Fits a T1 map using the 2 parameter model, and calculates the sign by trying all combinations - * @param data Data of shape (X,Y,TI) - * @param TI Inversion times - * @return Magnitude (A) and T1 mapping - */ -T1_2param fit_T1_2param(const hoNDArray>& data, const std::vector& TI); - -/** - * Fits a T1 map using the 2 parameter model - * @param data Data of shape (X,Y,TI) - * @param TI Inversion times - * @return Magnitude (A), inverse magnitude (B) and T1 mapping - */ -T1_3param fit_T1_3param(const hoNDArray& data, const std::vector& TI); -T1_3param fit_T1_3param(const hoNDArray>& data, const std::vector& TI); - - -hoNDArray calculate_error_map(const T1_3param& params, const hoNDArray& data, const std::vector& TI); - -struct registration_params { - unsigned int iterations = 40; - float regularization_sigma = 2.0f; - float step_size = 2.0; - float noise_sigma = 0.0f; -}; - -/** - * Performs registration on a T1 dataset by iteratively creating synthetic data based - * on a two parameter T1 fit, and registering it to the original data using intensity based - *registration. - * @param data Input data of shape (X,Y,TI) - * @param TI inversion times - * @param iterations Number of iterations to be used. - * @return Deformation vector fields for bringing each dataset into a common reference frame - **/ -hoNDArray> t1_registration(const hoNDArray>& data, - const std::vector& TI, - unsigned int iterations = 5, - registration_params params = {}); - -hoNDArray> t1_registration(const hoNDArray>& data, - const std::vector& TI, - hoNDArray> initial_vfield, - unsigned int iterations = 5, - registration_params params = {}); -hoNDArray> -multi_scale_t1_registration(const hoNDArray>& data, - const std::vector& TI, unsigned int levels = 3, - unsigned int iterations = 5, registration_params params = {}); - -hoNDArray> deform_groups(const hoNDArray>& data, - const hoNDArray>& vector_field); - -hoNDArray deform_groups(const hoNDArray& data, - const hoNDArray>& vector_field); - -hoNDArray predict_signal(const T1_2param& params, const std::vector& TI); - -hoNDArray predict_signal(const T1_3param& params, const std::vector& TI); - -hoNDArray phase_correct(const hoNDArray>& data, - const std::vector& TI); - -hoNDArray> register_groups_CMR(const hoNDArray& phase_corrected_data, - const hoNDArray& predicted, float hilbert_strength=12.0f); -/** - * Preforms registration on a T1 dataset by iteratively creating synthetic data. Uses the CMR motion - * correction code, and returns the deformed data - * @param data Input data of shape (X,Y,TI) - * @param TI inversion times - * @param iterations Number of iterations between synthetic and registration - * @return Motion corrected data - */ -hoNDArray> t1_moco_cmr(const hoNDArray>& data, - const std::vector& TI, unsigned int iterations); - -} // namespace Gadgetron::T1 diff --git a/toolboxes/fatwater/CMakeLists.txt b/toolboxes/fatwater/CMakeLists.txt deleted file mode 100644 index ab44533d0..000000000 --- a/toolboxes/fatwater/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -add_library(pingvin_toolbox_fatwater SHARED - fatwater.h - fatwater.cpp - graph_cut.cpp ImageGraph.cpp correct_frequency_shift.h correct_frequency_shift.cpp bounded_field_map.cpp) - -set_target_properties(pingvin_toolbox_fatwater PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_toolbox_fatwater - pingvin_toolbox_log - pingvin_toolbox_cpucore - pingvin_toolbox_cpucore_math - pingvin_toolbox_cpufft - armadillo - ) - -target_include_directories( - pingvin_toolbox_fatwater - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} - ) - -install(TARGETS pingvin_toolbox_fatwater - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install(FILES - fatwater.h - correct_frequency_shift.h - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) \ No newline at end of file diff --git a/toolboxes/fatwater/ImageGraph.cpp b/toolboxes/fatwater/ImageGraph.cpp deleted file mode 100644 index a0a823280..000000000 --- a/toolboxes/fatwater/ImageGraph.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "ImageGraph.h" - -template<> Gadgetron::vector_td Gadgetron::ImageGraph<2>::index_to_offset[4] = {Gadgetron::vector_td(-1,0), - Gadgetron::vector_td(1,0), - Gadgetron::vector_td(0,-1), - Gadgetron::vector_td(0,1)}; - - -template<> Gadgetron::vector_td Gadgetron::ImageGraph<3>::index_to_offset[6] = {Gadgetron::vector_td(-1,0,0), - Gadgetron::vector_td(1,0,0), - Gadgetron::vector_td(0,-1,0), - Gadgetron::vector_td(0,1,0), - Gadgetron::vector_td(0,0,-1), - Gadgetron::vector_td(0,0,1) - -}; - - diff --git a/toolboxes/fatwater/ImageGraph.h b/toolboxes/fatwater/ImageGraph.h deleted file mode 100644 index c703ae1c7..000000000 --- a/toolboxes/fatwater/ImageGraph.h +++ /dev/null @@ -1,397 +0,0 @@ -// -// Created by dch on 09/04/18. -// - -#ifndef IMAGEGRAPH_H -#define IMAGEGRAPH_H -#pragma once -# -#include - -#include -#include - -//template T& get(std::vector& vec, size_t i){ return vec[i];} -// -//template -//void put(std::vector &vec, size_t i, R val) { -// vec[i] = val; -//} - -#include -#include -#include "vector_td_utilities.h" - -namespace Gadgetron { - - template - class ImageGraph { - public: - - constexpr static char edges_per_vertex = 2 * D + 2; // 8 per vertex + source & sink - constexpr static char source_offset = 2 * D; - constexpr static char sink_offset = 2 * D + 1; - static Gadgetron::vector_td index_to_offset[2 * D]; - using vertex_descriptor = size_t; - - using vertices_size_type = size_t; - - using edges_size_type = size_t; - using edge_descriptor = size_t; - - class traversal_category : public boost::vertex_list_graph_tag, - public boost::edge_list_graph_tag, - public boost::incidence_graph_tag { - }; - - - using vertex_iterator = boost::counting_iterator; - using edge_iterator = boost::counting_iterator; - - - - - template ImageGraph(Args... args): ImageGraph(vector_td(args...)) { - - } - - ImageGraph(const vector_td& dims): dims_(dims){ - num_image_vertices_ = std::accumulate(std::begin(dims_),std::end(dims_),1,std::multiplies()); - num_vertices_ = num_image_vertices_ + 2; - num_edges_ = (edges_per_vertex + 2) * num_image_vertices_; - source_vertex = num_image_vertices_; - sink_vertex = source_vertex + 1; - - setup_reverse_edge_map(); - reset(); - } - - - void reset() { - edge_capacity_map = std::vector(num_edges_, 0); - edge_residual_capicty = std::vector(num_edges_, 0); - color_map = std::vector(num_vertices_, boost::default_color_type::gray_color); - vertex_distance = std::vector(num_vertices_, 0); - vertex_predecessor = std::vector(num_vertices_, 0); - - } - - vertex_iterator vertex_begin() const { - return vertex_iterator(0); - } - - vertex_iterator vertex_end() const { - return vertex_iterator(num_vertices_); - } - - size_t num_vertices() const { - return num_vertices_; - } - - - edge_iterator edge_begin() const { - return edge_iterator(0); - } - - edge_iterator edge_end() const { - return edge_iterator(num_edges_); - } - - - vertex_descriptor source(edge_descriptor e) const { - - size_t normal_vertex_id = e / edges_per_vertex; - if (normal_vertex_id < num_image_vertices_) { - return normal_vertex_id; - } - - size_t remainder = e - num_image_vertices_ * edges_per_vertex; - if (remainder < num_image_vertices_) { - return source_vertex; - } else { - return sink_vertex; - } - } - - - const vertex_descriptor target(edge_descriptor e) const { - - - size_t normal_vertex_id = e / edges_per_vertex; - if (normal_vertex_id < num_image_vertices_) { - size_t index_offset = e - normal_vertex_id * edges_per_vertex; - if (index_offset < edges_per_vertex - 2) { - vector_td offset = index_to_offset[index_offset]; - vector_td co = Gadgetron::idx_to_co(normal_vertex_id, dims_); - vector_td co2 = (co + offset + dims_) % dims_; - return Gadgetron::co_to_idx(co2, dims_); - } else { - if (index_offset == edges_per_vertex - 2) - return source_vertex; - return sink_vertex; - } - } else { - return e % num_image_vertices_; - } - } - - - std::pair out_edges(vertex_descriptor v) const { - if (v < num_image_vertices_) { - return std::make_pair(edge_iterator(v * edges_per_vertex), edge_iterator((v + 1) * edges_per_vertex)); - } else { - if (v == source_vertex) { - edge_descriptor source_start = num_image_vertices_ * edges_per_vertex; - return std::make_pair(edge_iterator(source_start), - edge_iterator(source_start + num_image_vertices_)); - } else { - edge_descriptor source_start = num_image_vertices_ * (edges_per_vertex + 1); - return std::make_pair(edge_iterator(source_start), - edge_iterator(source_start + num_image_vertices_)); - } - } - - } -// size_t out_degree(vertex_descriptor v) const; - - size_t out_degree(vertex_descriptor v) const { - if (v < num_image_vertices_) { - return edges_per_vertex; - } else { - return num_image_vertices_; - } - } - - - edge_descriptor reverse(edge_descriptor e) const { - - vertex_descriptor sv = source(e); - vertex_descriptor tv = target(e); - auto res = edge(tv,sv); - assert(res.second); - return res.first; - - } - - - std::pair edge(vertex_descriptor u, vertex_descriptor v) const { - - - - if ((u == source_vertex || u == sink_vertex) && (v == source_vertex || v == sink_vertex)) { - return std::make_pair(edge_descriptor(0), false); - } - edge_descriptor result; - - if (u == source_vertex) { - result = num_image_vertices_ * edges_per_vertex + v; - } else if (u == sink_vertex) { - result = num_image_vertices_ * (edges_per_vertex + 1) + v; - - } else if (v == source_vertex) { - result = u * edges_per_vertex + edges_per_vertex - 2; - } else if (v == sink_vertex) { - result = u * edges_per_vertex + edges_per_vertex - 1; - } else { - - vector_td co1 = Gadgetron::idx_to_co(u, dims_); - vector_td co2 = Gadgetron::idx_to_co(v, dims_); - - auto diff = co2 - co1; - for (int i = 0; i < D; i++){ //Fix wrapping boundary conditions - if (diff[i] != 0) { - if (diff[i] == (dims_[i] - 1)) diff[i] = -1; - if (diff[i] == (-dims_[i] + 1)) diff[i] = 1; - } - } - - auto res = std::accumulate(std::begin(diff),std::end(diff),0, [](auto v1, auto v2){ return v1+abs(v2);}); - if (res != 1) return std::make_pair(edge_descriptor(0),false); - - - int offset; - for (auto i = 0; i < D; i++){ - if (diff[i] == -1) offset = i*2; - else if (diff[i] == 1 ) offset = i*2+1; - } - - result = u * edges_per_vertex + offset; - } - - return std::make_pair(result,true); - - }; - - - size_t num_edges() const { - return num_edges_; - } - - edge_descriptor edge_from_source(vertex_descriptor idx){ - return source_vertex*edges_per_vertex+idx; - } - - edge_descriptor edge_to_sink(vertex_descriptor idx){ - return idx*edges_per_vertex+sink_offset; - } - - - - - std::vector edge_capacity_map; - std::vector edge_residual_capicty; - std::vector color_map; - std::vector vertex_distance; - std::vector vertex_predecessor; - std::vector reverse_edge_map; - - boost::identity_property_map vertex_index_map; -// ReverseEdgeMap reverse_edge_map; - - vertex_descriptor source_vertex; - vertex_descriptor sink_vertex; - private: - - void setup_reverse_edge_map() { - reverse_edge_map = std::vector(num_edges_); - for (edge_descriptor edge = 0; edge < num_edges_; edge++) { - reverse_edge_map[edge] = reverse(edge); - } - - } - - size_t num_vertices_; - size_t num_image_vertices_; - size_t num_edges_; - - Gadgetron::vector_td dims_; - - - }; -} - - - - - - - - - - - - - - - -template std::pair::edge_descriptor ,bool> edge(typename Gadgetron::ImageGraph::vertex_descriptor v1, typename Gadgetron::ImageGraph::vertex_descriptor v2, const Gadgetron::ImageGraph& g); - -namespace boost { - template std::pair::vertex_iterator, typename Gadgetron::ImageGraph::vertex_iterator > vertices(const Gadgetron::ImageGraph& g); - - template float* get(boost::edge_capacity_t, Gadgetron::ImageGraph &g); - - template float* get(boost::edge_residual_capacity_t, Gadgetron::ImageGraph &g); - - template boost::default_color_type* get(boost::vertex_color_t, Gadgetron::ImageGraph &g); - - template float* get(boost::vertex_distance_t, Gadgetron::ImageGraph &g); - - template const identity_property_map &get(boost::vertex_index_t, const Gadgetron::ImageGraph &g); - - template size_t* get(boost::edge_reverse_t, Gadgetron::ImageGraph &g); - - template size_t* get(boost::vertex_predecessor_t, Gadgetron::ImageGraph &g); - template const float* get(boost::edge_capacity_t, const Gadgetron::ImageGraph &g); - - template const float* get(boost::edge_residual_capacity_t, const Gadgetron::ImageGraph &g); - - template const boost::default_color_type* get(boost::vertex_color_t, const Gadgetron::ImageGraph &g); - - template const float* get(boost::vertex_distance_t, const Gadgetron::ImageGraph &g); - - - - template const size_t* get(boost::edge_reverse_t, const Gadgetron::ImageGraph &g); - template const size_t* get(boost::vertex_predecessor_t, const Gadgetron::ImageGraph &g); - - template float get(boost::edge_capacity_t, const Gadgetron::ImageGraph &g, size_t i); - - template size_t num_vertices(const Gadgetron::ImageGraph& g); - - template std::pair::edge_iterator, typename Gadgetron::ImageGraph::edge_iterator> edges(const Gadgetron::ImageGraph& g); - - template std::pair::edge_iterator,typename Gadgetron::ImageGraph::edge_iterator> out_edges(typename Gadgetron::ImageGraph::vertex_descriptor v, const Gadgetron::ImageGraph& g); - template size_t out_degree(typename Gadgetron::ImageGraph::vertex_descriptor v, const Gadgetron::ImageGraph& g); - template size_t num_edges(const Gadgetron::ImageGraph& g); - - - template typename Gadgetron::ImageGraph::vertex_descriptor source(typename Gadgetron::ImageGraph::edge_descriptor e, const Gadgetron::ImageGraph& g); - - template typename Gadgetron::ImageGraph::vertex_descriptor target(typename Gadgetron::ImageGraph::edge_descriptor e, const Gadgetron::ImageGraph& g); - -} - - -namespace boost { - - - -// typedef Gadgetron::ImageGraph* image_graph_ptr; -// typedef const Gadgetron::ImageGraph* image_const_graph_ptr; - - - - template struct graph_traits> { - typedef typename Gadgetron::ImageGraph::vertex_descriptor vertex_descriptor; - typedef typename Gadgetron::ImageGraph::edge_descriptor edge_descriptor; - typedef typename Gadgetron::ImageGraph::edge_iterator out_edge_iterator; - typedef void in_edge_iterator; - - typedef typename Gadgetron::ImageGraph::vertex_iterator vertex_iterator; - typedef typename Gadgetron::ImageGraph::edge_iterator edge_iterator; - typedef size_t vertices_size_type; - typedef size_t edges_size_type; - typedef size_t degree_size_type; - typedef directed_tag directed_category; - typedef typename Gadgetron::ImageGraph::traversal_category traversal_category; - - typedef disallow_parallel_edge_tag edge_parallel_category; - static edge_descriptor null_vertex(){ return std::numeric_limits::max();} - - - - }; -/* - template <> struct graph_traits { - typedef Gadgetron::ImageGraph::vertex_descriptor vertex_descriptor; - typedef Gadgetron::ImageGraph::edge_descriptor edge_descriptor; - typedef Gadgetron::ImageGraph::edge_iterator out_edge_iterator; - typedef void in_edge_iterator; - - typedef Gadgetron::ImageGraph::vertex_iterator vertex_iterator; - typedef Gadgetron::ImageGraph::edge_iterator edge_iterator; - typedef size_t vertices_size_type; - typedef size_t edge_size_type; - typedef size_t degree_size_type; - typedef directed_tag directed_category; - typedef Gadgetron::ImageGraph::traversal_category traversal_category; - - - };*/ - - - template struct property_map,edge_capacity_t>{ typedef float* type; typedef const float* const_type; }; - template struct property_map,edge_residual_capacity_t>{ typedef float* type; typedef const float* const_type;}; - template struct property_map,edge_reverse_t >{ typedef size_t* type; typedef const size_t* const_type;}; - - template struct property_map,vertex_color_t >{ typedef default_color_type* type; typedef const default_color_type* const_type;}; - template struct property_map,vertex_distance_t >{ typedef float* type; typedef const float* const_type;}; - template struct property_map,vertex_index_t >{ typedef identity_property_map type; typedef identity_property_map const_type;}; - template struct property_map,vertex_predecessor_t >{ typedef size_t* type; typedef const size_t* const_type;}; - -} - -#include "ImageGraph.hxx" - -#endif \ No newline at end of file diff --git a/toolboxes/fatwater/ImageGraph.hxx b/toolboxes/fatwater/ImageGraph.hxx deleted file mode 100644 index 7678fbd29..000000000 --- a/toolboxes/fatwater/ImageGraph.hxx +++ /dev/null @@ -1,146 +0,0 @@ -// -// Created by dch on 09/04/18. -// - -#include "ImageGraph.h" - - - template - std::pair::edge_descriptor, bool> - edge(typename Gadgetron::ImageGraph::vertex_descriptor v1, typename Gadgetron::ImageGraph::vertex_descriptor v2, - const Gadgetron::ImageGraph &g) { - return g.edge(v1, v2); - - }; - -namespace boost { - template - std::pair::vertex_iterator, typename Gadgetron::ImageGraph::vertex_iterator> - vertices(const Gadgetron::ImageGraph &g) { - - return std::make_pair(g.vertex_begin(), g.vertex_end()); - - }; - - - - - template - size_t num_vertices(const Gadgetron::ImageGraph &g) { - return g.num_vertices(); - } - - - template - size_t num_edges(const Gadgetron::ImageGraph &g) { - return g.num_edges(); - } - - - template - typename Gadgetron::ImageGraph::vertex_descriptor - source(typename Gadgetron::ImageGraph::edge_descriptor e, const Gadgetron::ImageGraph &g) { - return g.source(e); - } - - - template - typename Gadgetron::ImageGraph::vertex_descriptor - target(typename Gadgetron::ImageGraph::edge_descriptor e, const Gadgetron::ImageGraph &g) { - return g.target(e); - } - - - template - std::pair::edge_iterator, typename Gadgetron::ImageGraph::edge_iterator> - out_edges(typename Gadgetron::ImageGraph::vertex_descriptor v, const Gadgetron::ImageGraph &g) { - return g.out_edges(v); - }; - - - template - size_t out_degree(typename Gadgetron::ImageGraph::vertex_descriptor v, const Gadgetron::ImageGraph &g) { - return g.out_degree(v); - } - - - template - std::pair::edge_iterator, typename Gadgetron::ImageGraph::edge_iterator> - edges(const Gadgetron::ImageGraph &g) { - return std::make_pair(g.edge_begin(), g.edge_end()); - }; - - - template - float *get(edge_capacity_t, Gadgetron::ImageGraph &g) { - return g.edge_capacity_map.data(); - } - - template - float *get(edge_residual_capacity_t, Gadgetron::ImageGraph &g) { - return g.edge_residual_capicty.data(); - } - - template - default_color_type *get(vertex_color_t, Gadgetron::ImageGraph &g) { - return g.color_map.data(); - } - - template - float *get(vertex_distance_t, Gadgetron::ImageGraph &g) { - return g.vertex_distance.data(); - } - - template - const identity_property_map &get(vertex_index_t, const Gadgetron::ImageGraph &g) { - return g.vertex_index_map; - } - - template - size_t *get(edge_reverse_t, Gadgetron::ImageGraph &g) { - return g.reverse_edge_map.data(); - } - - template - size_t *get(vertex_predecessor_t, Gadgetron::ImageGraph &g) { - return g.vertex_predecessor.data(); - - } - - template - const float *get(edge_capacity_t, const Gadgetron::ImageGraph &g) { - return g.edge_capacity_map.data(); - } - - template - const float *get(edge_residual_capacity_t, const Gadgetron::ImageGraph &g) { - return g.edge_residual_capicty.data(); - } - - template - const default_color_type *get(vertex_color_t, const Gadgetron::ImageGraph &g) { - return g.color_map.data(); - } - - template - const float *get(vertex_distance_t, const Gadgetron::ImageGraph &g) { - return g.vertex_distance.data(); - } - - - template - const size_t *get(edge_reverse_t, const Gadgetron::ImageGraph &g) { - return g.reverse_edge_map.data(); - } - - template - const size_t *get(vertex_predecessor_t, const Gadgetron::ImageGraph &g) { - return g.vertex_predecessor.data(); - } - - template - float get(edge_capacity_t, Gadgetron::ImageGraph &g, size_t i) { - return g.edge_capacity_map[i]; - } -} - diff --git a/toolboxes/fatwater/bounded_field_map.cpp b/toolboxes/fatwater/bounded_field_map.cpp deleted file mode 100644 index b6a6f8565..000000000 --- a/toolboxes/fatwater/bounded_field_map.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// Created by dchansen on 9/4/18. -// - -#include "bounded_field_map.h" -#include -#include -#include -#include - -constexpr float PI = boost::math::constants::pi(); - - -namespace Gadgetron { - namespace FatWater { - namespace { - template - struct FieldMapModel { - - FieldMapModel(const Parameters ¶meters, - const std::array, N> &data) : TEs_(parameters.echo_times_s) { - - std::transform(data.begin(), data.end(), angles.begin(), [](auto c) { return arg(c); }); - - - auto data_norm = std::accumulate(data.begin(), data.end(), 0.0, - [](auto acc, auto c) { return acc + norm(c); }); - for (int i = 0; i < data.size(); i++) { - for (int j = 0; j < data.size(); j++) { - weights[j + i * N] = norm(data[i] * data[j]) / data_norm; - } - } - } - - - float operator()(float field_value) const { - - float result = 0; - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) { - result += magnitude_internal(field_value, TEs_[i], TEs_[j], angles[i], angles[j], - weights[j + i * N]); - } - } - return result; - } - - float magnitude_internal(float field_value, float time1, float time2, float angle1, float angle2, - float weight) const { - assert(weight >= 0); - return weight * (1.0f - std::cos(field_value * (time1 - time2) + angle1 - angle2)); - - } - - const std::vector TEs_; - std::array weights; - std::array angles; - - }; - - - template - void bounded_field_map_N(Gadgetron::hoNDArray &field_map, - const Gadgetron::hoNDArray> &input_data, - const Gadgetron::FatWater::Parameters ¶meters, - float delta_field) { - - - const size_t X = input_data.get_size(0); - const size_t Y = input_data.get_size(1); - const size_t Z = input_data.get_size(2); - const size_t S = input_data.get_size(5); - - #pragma omp parallel for collapse(2) - for (int ky = 0; ky < Y; ky++) { - for (size_t kx = 0; kx < X; kx++) { - - std::array, N> signal; - - for (int k3 = 0; k3 < S; k3++) { - signal[k3] = input_data(kx, ky, 0, 0, 0, k3, 0); - } - - - auto model = FieldMapModel(parameters, signal); - - auto result_pair = boost::math::tools::brent_find_minima(model, field_map(kx,ky)-delta_field,field_map(kx,ky)+delta_field, 24); - field_map(kx, ky) = result_pair.first; - } - } - - - - } - } - - void bounded_field_map(Gadgetron::hoNDArray &field_map, - const Gadgetron::hoNDArray> &input_data, - const Gadgetron::FatWater::Parameters ¶meters, - float delta_field - ) { - - - if (input_data.get_size(4) > 1) throw std::runtime_error("Only single repetition supported"); - - switch (input_data.get_size(5)) { - case 2: - bounded_field_map_N<2>(field_map, input_data, parameters, delta_field); - break; - case 3: - bounded_field_map_N<3>(field_map, input_data, parameters, delta_field); - break; - case 4: - bounded_field_map_N<4>(field_map, input_data, parameters, delta_field); - break; - case 5: - bounded_field_map_N<5>(field_map, input_data, parameters, delta_field); - break; - case 6: - bounded_field_map_N<6>(field_map, input_data, parameters, delta_field); - break; - case 7: - bounded_field_map_N<7>(field_map, input_data, parameters, delta_field); - break; - case 8: - bounded_field_map_N<8>(field_map, input_data, parameters, delta_field); - break; - default: - throw std::runtime_error("Unsupported number of echoes"); - - } - } - - } -} - diff --git a/toolboxes/fatwater/bounded_field_map.h b/toolboxes/fatwater/bounded_field_map.h deleted file mode 100644 index 06b0ae600..000000000 --- a/toolboxes/fatwater/bounded_field_map.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "fatwater.h" - - -namespace Gadgetron { - namespace FatWater { - void bounded_field_map(hoNDArray &field_map, - const hoNDArray> &input_data, - const Parameters ¶meters, float delta_field); - } -} - - diff --git a/toolboxes/fatwater/correct_frequency_shift.cpp b/toolboxes/fatwater/correct_frequency_shift.cpp deleted file mode 100644 index ce184c946..000000000 --- a/toolboxes/fatwater/correct_frequency_shift.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Created by dchansen on 6/16/18. -// -#include -#include -#include "correct_frequency_shift.h" -#include "hoNDFFT.h" -#include "hoNDArray_elemwise.h" -namespace Gadgetron{ - namespace FatWater { - - using namespace std::complex_literals; - static constexpr float PI = boost::math::constants::pi(); - - void correct_frequency_shift(hoNDArray> &species_images, const Parameters ¶meters){ - - - uint16_t X = species_images.get_size(0); - uint16_t Y = species_images.get_size(1); - uint16_t Z = species_images.get_size(2); - uint16_t CHA = species_images.get_size(3); - uint16_t N = species_images.get_size(4); - uint16_t S = species_images.get_size(5); - uint16_t LOC = species_images.get_size(6); - - - - std::vector sub_dimension = {X,Y,Z,CHA,N,1,1}; - auto data_ptr = species_images.get_data_ptr(); - - - hoNDFFT::instance()->fft(&species_images,0); - - for (int kspecies = 0; kspecies < parameters.species.size(); kspecies++){ - - auto& species = parameters.species[kspecies]; - - auto mean_frequency_offset = std::accumulate( - species.amplitude_frequency_pairs.begin(), species.amplitude_frequency_pairs.end(),0.0f, - [](auto v, auto pair){ return v+pair.first.real()*pair.second;} - ) / - std::accumulate( - species.amplitude_frequency_pairs.begin(),species.amplitude_frequency_pairs.end(), 0.0f, - [](auto v, auto pair) { return v + pair.first.real();}); - mean_frequency_offset *= parameters.field_strength_T*parameters.gyromagnetic_ratio_Mhz; - - if (std::abs(mean_frequency_offset) < 1.0 ) continue; - - - - hoNDArray> phase_ramp(X); - - for (int i = 0; i < phase_ramp.get_number_of_elements(); i++){ - phase_ramp[i] = std::exp(2if*PI*parameters.sample_time_us*1e-6f*float(i)*mean_frequency_offset); - } - - //Kristoffer will have a field day with this. - for (int kL = 0; kL < LOC; kL++) - for (int kN = 0; kN < N; kN++) - for (int kCHA = 0; kCHA < CHA; kCHA++) - for (int kZ = 0; kZ < Z; kZ++) - for (int kY = 0; kY < Y; kY++) - for (int kX = 0; kX < Y; kX++) - species_images(kX,kY,kZ,kCHA,kN,kspecies,kL) *= phase_ramp[kX]; - - - - - } -// - hoNDFFT::instance()->ifft(&species_images,0); - - - - - - - - - - } - } -} - diff --git a/toolboxes/fatwater/correct_frequency_shift.h b/toolboxes/fatwater/correct_frequency_shift.h deleted file mode 100644 index 65b46b788..000000000 --- a/toolboxes/fatwater/correct_frequency_shift.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// Created by dchansen on 6/16/18. -// -#pragma once - -#include -#include "fatwater.h" -#include "hoNDArray.h" -namespace Gadgetron{ - namespace FatWater { - - void correct_frequency_shift(hoNDArray> &species_images, const Parameters ¶ms); - - - } -} diff --git a/toolboxes/fatwater/fatwater.cpp b/toolboxes/fatwater/fatwater.cpp deleted file mode 100644 index 8db0f7d5f..000000000 --- a/toolboxes/fatwater/fatwater.cpp +++ /dev/null @@ -1,661 +0,0 @@ -#include "fatwater.h" - -#include "hoMatrix.h" -#include "hoNDArray_linalg.h" -#include "hoNDArray_utils.h" -#include "hoNDArray_elemwise.h" -#include "hoNDArray_reductions.h" -#include "hoArmadillo.h" - -#include - -#include -#include - -#include -#include -#include -#include "graph_cut.h" - -#include "hoNDArray_math.h" - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include "bounded_field_map.h" - -using namespace boost; - - -namespace Gadgetron { - namespace FatWater { - using namespace std::complex_literals; - static constexpr float PI = boost::math::constants::pi(); - static std::mt19937 rng_state(4242); - - - hoNDArray> find_local_minima(const hoNDArray &residuals, float threshold = 0.00f) { - - - auto threshold_signal = sum(residuals, 0); - threshold_signal /= max(threshold_signal); - sqrt_inplace(&threshold_signal); - - auto min_residuals = min(residuals, 0); - auto max_residuals = max(residuals, 0); - - - const auto Y = residuals.get_size(2); - const auto X = residuals.get_size(1); - hoNDArray> result(X, Y); - const auto steps = residuals.get_size(0); - size_t count = 0; - for (size_t k2 = 0; k2 < Y; k2++) { - for (size_t k1 = 0; k1 < X; k1++) { - - std::vector minima; -// if (threshold_signal(k1, k2) > threshold) { - for (size_t k0 = 1; k0 < steps - 1; k0++) { - if ((residuals(k0, k1, k2) < residuals(k0 - 1, k1, k2)) && - (residuals(k0 + 1, k1, k2) >= residuals(k0, k1, k2))) { - minima.push_back(k0); - } - - } -// } - if (minima.size() < 2) count++; - result(k1, k2) = std::move(minima); - } - } - - GDEBUG("COUNT DRACULA %i\n", count); - return result; - } - - hoNDArray approx_second_derivative(const hoNDArray &residuals, - const hoNDArray> &local_min_indices, - float step_size) { - hoNDArray second_deriv(local_min_indices.dimensions()); - - const auto Y = second_deriv.get_size(1); - const auto X = second_deriv.get_size(0); - const auto nfields = residuals.get_size(0); - - for (uint16_t k2 = 0; k2 < Y; k2++) { - for (uint16_t k1 = 0; k1 < X; k1++) { - - auto minimum = std::min_element(&residuals(1, k1, k2), &residuals(nfields - 1, k1, k2)) - - &residuals(0, k1, k2); - - auto sd = - (residuals(minimum - 1, k1, k2) + residuals(minimum + 1, k1, k2) - - 2 * residuals(minimum, k1, k2)) / (step_size * step_size); - - second_deriv(k1, k2) = sd; - - } - } - - return second_deriv; - - - } - - - hoNDArray - create_field_map(const hoNDArray &field_map_index, const std::vector &field_map_strengths) { - const uint16_t max_val = field_map_strengths.size() - 1; - hoNDArray field_map(field_map_index.dimensions()); - std::transform(field_map_index.begin(), field_map_index.end(), field_map.begin(), - [&](uint16_t i) { return field_map_strengths[std::min(i, max_val)]; }); - return field_map; - } - - - hoNDArray create_field_map_proposal1(const hoNDArray &field_map_index, - const hoNDArray> &minima, - const hoNDArray &residuals, - const std::vector &field_map_strengths, float fat_freq, - float dF, float dTE) { - - const size_t elements = field_map_index.get_number_of_elements(); - hoNDArray proposed_field_map_index(field_map_index.dimensions()); - const size_t field_maps = field_map_strengths.size(); - std::uniform_int_distribution coinflip(0, 1); - int jump; - if (coinflip(rng_state)) { - jump = round(std::abs(fat_freq / dF)); - - } else { - jump = round((1.0 / dTE - std::abs(fat_freq)) / dF); - } - - - for (size_t i = 0; i < elements; i++) { - auto &mins = minima[i]; - auto fbi = field_map_index[i]; - auto fqmi = std::find_if(mins.begin(), mins.end(), - [&](auto fqi) { return fqi > fbi + 20; }); //Find smallest - proposed_field_map_index[i] = (fqmi == mins.end()) ? std::min(fbi + jump, field_maps - 1) : *fqmi; - } - - return proposed_field_map_index; - - - } - - hoNDArray create_field_map_proposal2(const hoNDArray &field_map_index, - const hoNDArray> &minima, - const hoNDArray &residuals, - const std::vector &field_map_strengths, float fat_freq, - float dF, float dTE) { - - const size_t elements = field_map_index.get_number_of_elements(); - hoNDArray proposed_field_map_index(field_map_index.dimensions()); - std::uniform_int_distribution coinflip(0, 1); - int jump; - if (coinflip(rng_state)) { - jump = round(std::abs(fat_freq / dF)); - } else { - jump = round((1.0 / dTE - std::abs(fat_freq)) / dF); - } - - for (size_t i = 0; i < elements; i++) { - auto &mins = minima[i]; - int fbi = field_map_index[i]; - auto fqmi = std::find_if(mins.rbegin(), mins.rend(), - [&](auto fqi) { return fqi < (fbi - 20); }); //Find smallest - proposed_field_map_index[i] = (fqmi == mins.rend()) ? std::max(fbi - jump, 0) : *fqmi; - } - - return proposed_field_map_index; - - - } - - hoNDArray - create_field_map_proposal_standard(const hoNDArray &field_map_index, int sign, - uint16_t max_field_value) { - - - std::uniform_int_distribution rng(1, 3); - - int step_size = sign * rng(rng_state); -// int step_size = sign; - hoNDArray proposed_field_map_index(field_map_index.dimensions()); - std::transform(field_map_index.begin(), field_map_index.end(), proposed_field_map_index.begin(), - [&](uint16_t j) { - return uint16_t(std::min(std::max(j + step_size, 0), int(max_field_value))); - }); - - return proposed_field_map_index; - } - - hoNDArray - solve_MRF(const Config &config, const std::vector &field_map_strengths, - const hoNDArray &residual, const hoNDArray> &local_min_indices, - const hoNDArray &second_deriv, float fat_freq, float dF, float dTE) { - - hoNDArray fmIndex(local_min_indices.dimensions()); - - std::uniform_int_distribution coinflip(0, 2); - fmIndex.fill(field_map_strengths.size() / 2); - - hoNDArray fmIndex_update; - for (int i = 0; i < config.number_of_iterations; i++) { - if (coinflip(rng_state) == 0 || i < 15) { - if (!(i % 2)) { - fmIndex_update = create_field_map_proposal1(fmIndex, local_min_indices, residual, - field_map_strengths, fat_freq, dF, dTE); - } else { - fmIndex_update = create_field_map_proposal2(fmIndex, local_min_indices, residual, - field_map_strengths, fat_freq, dF, dTE); - } - } else { - fmIndex_update = create_field_map_proposal_standard(fmIndex, std::pow(-1, i), - field_map_strengths.size() - 1); - } - - fmIndex = update_field_map(fmIndex, fmIndex_update, residual, second_deriv); - } - - return fmIndex; - } - - arma::Mat> - calculate_psi_matrix(const std::vector &echoTimes, - const arma::Mat> &phiMatrix, float r2star) { - arma::Mat> psiMatrix(phiMatrix.n_rows, phiMatrix.n_cols); - for (int k1 = 0; k1 < phiMatrix.n_rows; k1++) { - auto curModulation = exp(-r2star * (echoTimes[k1] - echoTimes[0])); - for (int k2 = 0; k2 < phiMatrix.n_cols; k2++) { - psiMatrix(k1, k2) = phiMatrix(k1, k2) * curModulation; - } - } - - - return psiMatrix; - } - - - hoNDArray>> - calculate_projection_matrices(const std::vector &echo_times, - const arma::Mat> &phiMatrix, - const std::vector &field_map_strengths, - const std::vector &r2stars) { - - auto num_fm = field_map_strengths.size(); - auto num_r2star = r2stars.size(); - hoNDArray>> Ps(num_fm, num_r2star); - size_t nte = echo_times.size(); - -#pragma omp parallel for - for (int k3 = 0; k3 < num_fm; k3++) { - - float fm = field_map_strengths[k3]; - arma::Col> b_shifts(nte); - for (int kt = 0; kt < nte; kt++) - b_shifts[kt] = std::exp(2if * PI * (echo_times[kt] - echo_times[0]) * fm); - for (int k4 = 0; k4 < num_r2star; k4++) { - float r2star = r2stars[k4]; - - arma::Mat> psiMatrix = calculate_psi_matrix(echo_times, phiMatrix, - r2star); - Ps(k3, k4) = arma::diagmat(b_shifts) * (arma::eye>>(nte, nte) - - psiMatrix * arma::pinv(psiMatrix)) * - arma::diagmat(arma::conj(b_shifts)); - - } - } - return Ps; - } - - - - - hoNDArray - calculate_r2star_map(const hoNDArray > &data, const hoNDArray &field_map, - const std::vector &r2star_values, - const arma::Mat> &phiMatrix, const std::vector &echoTimes) { - using cMat = arma::Mat>; - uint16_t X = data.get_size(0); - uint16_t Y = data.get_size(1); - uint16_t Z = data.get_size(2); - uint16_t CHA = data.get_size(3); - uint16_t N = data.get_size(4); - uint16_t S = data.get_size(5); - uint16_t LOC = data.get_size(6); - auto nte = phiMatrix.n_rows; - - - auto data_corrected = data; - - for (int kS = 0; kS < S; kS++) { - for (int kN = 0; kN < N; kN++) { - for (int kcha = 0; kcha < CHA; kcha++) { - for (int ky = 0; ky < Y; ky++) { - for (int kx = 0; kx < X; kx++) { - data_corrected(kx, ky, 0, kcha, kN, kS) *= std::exp( - -2if * PI * field_map(kx, ky) * echoTimes[kS]); - } - } - } - } - } - - - std::vector>> Ps; - for (auto r2star : r2star_values) { - - auto psiMatrix = calculate_psi_matrix(echoTimes, phiMatrix, - r2star); - Ps.emplace_back( - arma::eye>>(nte, nte) - psiMatrix * arma::pinv(psiMatrix) - ); - - } - - - hoNDArray r2star_map(field_map.dimensions()); - -#pragma omp parallel for collapse(2) - for (int k2 = 0; k2 < Y; k2++) { - for (int k1 = 0; k1 < X; k1++) { - // Get current signal - std::vector signals(CHA, cMat(S, N)); - for (int cha = 0; cha < CHA; cha++) { - auto &tempSignal = signals[cha]; - for (int k4 = 0; k4 < N; k4++) { - for (int k5 = 0; k5 < S; k5++) { - tempSignal(k5, k4) = data_corrected(k1, k2, 0, cha, k4, k5, 0); - - } - } - } - - - float minResidual = std::numeric_limits::max(); - std::vector field_map_strengths = {field_map(k1, k2)}; - - - for (int kr2 = 0; kr2 < r2star_values.size(); kr2++) { - - float curResidual = 0; - - for (int cha = 0; cha < CHA; cha++) { - // Apply projector - arma::Mat> projected = Ps[kr2] * signals[cha]; - curResidual += std::accumulate(projected.begin(), projected.end(), 0.0f, - [](auto v1, auto v2) { - return v1 + - std::norm(v2); - }); - } - if (curResidual < minResidual) { - minResidual = curResidual; - r2star_map(k1, k2) = r2star_values[kr2]; - } - - } - - - } - } - - return r2star_map; - } - - - std::tuple, hoNDArray> - calculate_residual_and_r2star(const hoNDArray> &data, const Parameters ¶meters, - const arma::Mat> &phi, - const std::vector &field_strengths, - const std::vector &r2star_values) { - using cMat = arma::Mat>; - uint16_t X = data.get_size(0); - uint16_t Y = data.get_size(1); - uint16_t Z = data.get_size(2); - uint16_t CHA = data.get_size(3); - uint16_t N = data.get_size(4); - uint16_t S = data.get_size(5); - uint16_t LOC = data.get_size(6); - - - auto projection_matrices = calculate_projection_matrices(parameters.echo_times_s, phi, field_strengths, - r2star_values); - - auto result = std::make_tuple(hoNDArray(field_strengths.size(), X, Y, Z), - hoNDArray(X, Y, Z, field_strengths.size())); - - auto &residual = std::get<0>(result); - auto &r2starIndex = std::get<1>(result); - -#pragma omp parallel for collapse(3) - for (int kz = 0; kz < Z; kz++) { - for (int ky = 0; ky < Y; ky++) { - for (int kx = 0; kx < X; kx++) { - - std::vector signals(CHA, cMat(S, N)); - for (int cha = 0; cha < CHA; cha++) { - auto &tempSignal = signals[cha]; - for (int kn = 0; kn < N; kn++) { - for (int ks = 0; ks < S; ks++) { - tempSignal(ks, kn) = data(kx, ky, kz, cha, kn, ks, 0); - } - } - } - - for (int kf = 0; kf < field_strengths.size(); kf++) { - - float minResidual = std::numeric_limits::max(); - - for (int kr = 0; kr < r2star_values.size(); kr++) { - // Apply projector - float curResidual = 0; - for (int cha = 0; cha < CHA; cha++) { - arma::Mat> projected = - projection_matrices(kf, kr) * signals[cha]; - curResidual += std::accumulate(projected.begin(), projected.end(), 0.0f, - [](auto v1, auto v2) { - return v1 + - std::norm(v2); - }); - } - if (curResidual < minResidual) { - minResidual = curResidual; - r2starIndex(kx, ky, kz, kf) = kr; - } - } - residual(kf, kx, ky, kz) = minResidual; - - } - } - } - } - - return result; - } - - hoNDArray> - separate_species(const hoNDArray> &data, - const arma::Mat> &phiMatrix, hoNDArray &r2star_map, - hoNDArray &field_map, const Parameters ¶meters) { - - using cMat = arma::Mat>; - uint16_t X = data.get_size(0); - uint16_t Y = data.get_size(1); - uint16_t Z = data.get_size(2); - uint16_t CHA = data.get_size(3); - uint16_t N = data.get_size(4); - uint16_t S = data.get_size(5); - uint16_t LOC = data.get_size(6); - hoNDArray > out(X, Y, Z, CHA, N, parameters.species.size(), - LOC); // S dimension gets replaced by water/fat stuff - -#pragma omp parallel for collapse(3) - for (int kz = 0; kz < Z; kz++) { - for (int ky = 0; ky < Y; ky++) { - for (int kx = 0; kx < X; kx++) { - std::vector signals(CHA, cMat(S, N)); - - // Get current signal - for (int cha = 0; cha < CHA; cha++) { - auto &tempSignal = signals[cha]; - for (int kn = 0; kn < N; kn++) { - for (int ks = 0; ks < S; ks++) { - tempSignal(ks, kn) = data(kx, ky, kz, cha, kn, ks, 0); - } - } - } - - auto fm = field_map(kx, ky); - auto r2star = r2star_map(kx, ky); - - arma::Mat> psiMatrix = calculate_psi_matrix(parameters.echo_times_s, - phiMatrix,r2star); - - auto nte = parameters.echo_times_s.size(); - arma::Col> b_shifts(nte); - for (int kt = 0; kt < nte; kt++) - b_shifts[kt] = std::exp( - 2if * PI * (parameters.echo_times_s[kt] - parameters.echo_times_s[0]) * fm); - psiMatrix = arma::diagmat(b_shifts) * psiMatrix; - // Solve for water and fat - - for (int cha = 0; cha < CHA; cha++) { - arma::Mat> curWaterFat = arma::solve(psiMatrix, signals[cha]); - for (int kn = 0; kn < N; kn++) { - for (int kspecies = 0; kspecies < - parameters.species.size(); kspecies++) { // 2 elements for water and fat currently - out(kx, ky, kz, cha, kn, kspecies, 0) = curWaterFat(kspecies, kn); - } - } - } - - } - } - } - return out; - } - - - arma::Mat> - calculatePhiMatrix(const Parameters parameters) { - - auto echoTimes = parameters.echo_times_s; - - auto nte = echoTimes.size(); - auto nspecies = parameters.species.size(); - typedef arma::Mat> Cmat; - Cmat phiMatrix = arma::zeros(nte, nspecies); - for (int k1 = 0; k1 < nte; k1++) { - for (int k2 = 0; k2 < nspecies; k2++) { - auto &species = parameters.species[k2]; - auto npeaks = species.amplitude_frequency_pairs.size(); - for (int k3 = 0; k3 < npeaks; k3++) { - auto relAmp = species.amplitude_frequency_pairs[k3].first; - auto freq_hz = parameters.field_strength_T * parameters.gyromagnetic_ratio_Mhz * - species.amplitude_frequency_pairs[k3].second; - phiMatrix(k1, k2) += relAmp * exp(2if * PI * echoTimes[k1] * freq_hz); - - } - - } - } - return phiMatrix; - } - - - std::vector linspace(const std::pair &range, unsigned int count) { - std::vector result(count); - result[0] = range.first; - for (int i = 1; i < count; i++) { - result[i] = range.first + i * (range.second - range.first) / (count - 1); - } - return result; - } - - std::complex mean_frequency(const Parameters ¶meters) { - ChemicalSpecies fat = parameters.species[1]; - auto average_fat_freq = - accumulate(fat.amplitude_frequency_pairs.begin(), fat.amplitude_frequency_pairs.end(), std::complex(0.0), - [](auto val, auto tup) { - return val + std::get<0>(tup) * std::get<1>(tup); - }) / - accumulate(fat.amplitude_frequency_pairs.begin(), fat.amplitude_frequency_pairs.end(), std::complex(0.0), - [](auto val, auto tup) { return val + std::get<0>(tup); }); - average_fat_freq *= parameters.field_strength_T * parameters.gyromagnetic_ratio_Mhz; - return average_fat_freq; - } - - std::tuple, hoNDArray> - calculate_field_map(const hoNDArray> &data, const Parameters ¶meters, - const Config &config, - const std::complex &average_fat_freq, const arma::Mat> &phi, - const std::vector &field_map_strengths); - - FatWater::Output - fatwater_separation(const hoNDArray > &data, Parameters parameters, - Config config) { - - uint16_t X = data.get_size(0); - uint16_t Y = data.get_size(1); - uint16_t Z = data.get_size(2); - uint16_t CHA = data.get_size(3); - uint16_t N = data.get_size(4); - uint16_t S = data.get_size(5); - uint16_t LOC = data.get_size(6); - - - auto echo_times = parameters.echo_times_s; - GDEBUG("In toolbox - Field Strength: %f T \n", parameters.field_strength_T); - for (auto &te: echo_times) { - GDEBUG("In toolbox - Echo time: %f seconds \n", te); - } - GDEBUG("In toolbox - PrecessionIsClockwise: %d \n", parameters.precession_is_clockwise); - - //Get or set some algorithm parameters - - std::complex average_fat_freq = mean_frequency(parameters); - - - arma::Mat> phi = calculatePhiMatrix(parameters); - - std::vector field_map_strengths = linspace(config.frequency_range, - config.number_of_frequency_samples); - - - hoNDArray field_map, r2star_map; - std::tie(field_map, r2star_map) = calculate_field_map(data, parameters, config, average_fat_freq, phi, - field_map_strengths); - - - auto species = separate_species(data, phi, r2star_map, field_map, parameters); - - if (config.do_gradient_descent) { - bounded_field_map(field_map, data, parameters, (field_map_strengths[1] - field_map_strengths[0])*2); - species = separate_species(data, phi, r2star_map, field_map, parameters); - } - - return Output{std::move(species), std::move(field_map), std::move(r2star_map)}; - } - - std::tuple, hoNDArray> - calculate_field_map(const hoNDArray> &data, const Parameters ¶meters, - const Config &config, - const std::complex &average_fat_freq, const arma::Mat> &phi, - const std::vector &field_map_strengths) { - - - std::vector r2stars_fine = linspace(config.r2_range, config.number_of_r2_fine_samples); - std::vector r2stars = linspace(config.r2_range, config.number_of_r2_samples); - - auto data_scaled = data; - for (int downsamples = 0; downsamples < config.downsamples; downsamples++) - data_scaled = downsample, 2>(data_scaled); - - hoNDArray residual; - hoNDArray r2starIndex; - std::tie(residual, r2starIndex) = calculate_residual_and_r2star(data_scaled, parameters, phi, - field_map_strengths, - r2stars); - - auto dF = field_map_strengths[1] - field_map_strengths[0]; - - hoNDArray> local_min_indices = find_local_minima(residual); - - hoNDArray lambda_map = approx_second_derivative(residual, local_min_indices, dF); - lambda_map += mean(&lambda_map) * config.lambda_extra; - lambda_map *= config.lambda * dF * dF; - - hoNDArray fmIndex = solve_MRF(config, field_map_strengths, residual, local_min_indices, - lambda_map, abs(average_fat_freq), dF, - parameters.echo_times_s[1] - parameters.echo_times_s[0]); - - - hoNDArray field_map = create_field_map(fmIndex, field_map_strengths); - - if (config.downsamples) { - field_map = upsample_spline(field_map,std::pow(2,config.downsamples)); - } -// fmIndex = upsample(&fmIndex); - - auto r2star_map = calculate_r2star_map(data, field_map, r2stars_fine, phi, - parameters.echo_times_s); - - -// r2star_map = upsample(&r2star_map); - return std::make_tuple(std::move(field_map), std::move(r2star_map)); - } - - - } -} diff --git a/toolboxes/fatwater/fatwater.h b/toolboxes/fatwater/fatwater.h deleted file mode 100644 index 42b344293..000000000 --- a/toolboxes/fatwater/fatwater.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef FATWATER_H -#define FATWATER_H - -#include -#include - -#include "hoNDArray.h" - -namespace Gadgetron -{ - namespace FatWater { - - struct Config { - std::pair frequency_range = {-500, 500}; - size_t number_of_frequency_samples = 200; - - std::pair r2_range = {5, 500}; - size_t number_of_r2_samples = 5; - size_t number_of_r2_fine_samples = 200; - - size_t number_of_iterations = 40; - - float lambda = 0.02; - float lambda_extra = 0.01; - bool do_gradient_descent = true; - unsigned int downsamples = 0; - - - }; - - /** - Amplitudes and frequences (in ppm) - */ - struct ChemicalSpecies { - std::string name; - std::vector, float> > amplitude_frequency_pairs; - }; - - - struct Output { - hoNDArray> images; - hoNDArray field_map; - hoNDArray r2star_map; - }; - - struct Parameters { - - float field_strength_T; - bool precession_is_clockwise; - float gyromagnetic_ratio_Mhz = 42.57747892; - float sample_time_us; - - std::vector echo_times_s; - std::vector species; - - }; - - - - - /** - Main interface for water fat separation. - - data array is assumed to be a 7D array [X, Y, Z, CHA, N, S, LOC] - - */ - Output - fatwater_separation(const hoNDArray > &data, Parameters p, Config config); - } -} - -#endif //FATWATER_H diff --git a/toolboxes/fatwater/graph_cut.cpp b/toolboxes/fatwater/graph_cut.cpp deleted file mode 100644 index a9d3b1613..000000000 --- a/toolboxes/fatwater/graph_cut.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// -// Created by david on 6/7/2018. -// - -#include -#include "ImageGraph.h" -#include -#include "graph_cut.h" - - -namespace { - using namespace Gadgetron; - static std::mt19937 rng_state(4242); - - - template - void update_regularization_edge(ImageGraph &graph, const hoNDArray &field_map, - const hoNDArray &proposed_field_map, - const hoNDArray &second_deriv, const size_t idx, const size_t idx2, - const size_t edge_idx, float scaling) { - - int f_value1 = field_map[idx]; - int pf_value1 = proposed_field_map[idx]; - int f_value2 = field_map[idx2]; - int pf_value2 = proposed_field_map[idx2]; - int a = std::norm(f_value1 - f_value2); - int b = std::norm(f_value1 - pf_value2); - int c = std::norm(pf_value1 - f_value2); - int d = std::norm(pf_value1 - pf_value2); - - float weight = b + c - a - d; - - assert(weight >= 0); - float lambda = std::max(std::min(second_deriv[idx], second_deriv[idx2]), 0.0f) * scaling; - weight *= lambda; - - assert(lambda >= 0); - - auto &capacity_map = graph.edge_capacity_map; - - capacity_map[edge_idx] += weight; - { - float aq = lambda * (c - a); - - if (aq > 0) { - capacity_map[graph.edge_from_source(idx)] += aq; - - } else { - capacity_map[graph.edge_to_sink(idx)] -= aq; - } - } - - { - float aj = lambda * (d - c); - if (aj > 0) { - capacity_map[graph.edge_from_source(idx2)] += aj; - - } else { - capacity_map[graph.edge_to_sink(idx2)] -= aj; - } - } - - - } - - template - ImageGraph make_graph(const hoNDArray &field_map, const hoNDArray &proposed_field_map, - const hoNDArray &residual_diff_map, const hoNDArray &second_deriv) { - - const auto dims = vector_td(field_map.get_size(0),field_map.get_size(1),field_map.get_size(2)); - - vector_td graph_dims; - for (int i = 0; i < D; i++) graph_dims[i] = dims[i]; - - ImageGraph graph = ImageGraph(graph_dims); - - auto &capacity_map = graph.edge_capacity_map; - //Add regularization edges - - for (size_t kz = 0; kz < dims[2]; kz++) { - for (size_t ky = 0; ky < dims[1]; ky++) { - for (size_t kx = 0; kx < dims[0]; kx++) { - size_t idx = kz*dims[1]*dims[0]+ky * dims[0] + kx; - - - if (kx < (dims[0] - 1)) { - size_t idx2 = idx + 1; - - update_regularization_edge(graph, field_map, proposed_field_map, second_deriv, idx, idx2, - graph.edge(idx, idx2).first, 1); - } - - - if (ky < (dims[1] - 1)) { - size_t idx2 = idx + dims[0]; - update_regularization_edge(graph, field_map, proposed_field_map, second_deriv, idx, idx2, - graph.edge(idx, idx2).first, 1); - } - - if (kz < (dims[2] - 1)) { - size_t idx2 = idx + dims[0]*dims[1]; - update_regularization_edge(graph, field_map, proposed_field_map, second_deriv, idx, idx2, - graph.edge(idx, idx2).first, 1); - } - - float residual_diff = residual_diff_map[idx]; - - if (residual_diff > 0) { - capacity_map[graph.edge_to_sink(idx)] += int(residual_diff); - - } else { - capacity_map[graph.edge_from_source(idx)] -= int(residual_diff); - } - - } - } - } - - return graph; - } - - template - std::vector - graph_cut(const hoNDArray &field_map_index, const hoNDArray &proposed_field_map_index, - const hoNDArray &lambda_map, const hoNDArray &residual_diff_map) { - - ImageGraph graph = make_graph(field_map_index, proposed_field_map_index, residual_diff_map, - lambda_map); - - float flow = boost::boykov_kolmogorov_max_flow(graph, graph.source_vertex, graph.sink_vertex); - - return std::move(graph.color_map); - } - -} -namespace Gadgetron { - - - hoNDArray - update_field_map(const hoNDArray &field_map_index, const hoNDArray &proposed_field_map_index, - const hoNDArray &residuals_map, const hoNDArray &lambda_map) { - - - hoNDArray residual_diff_map(field_map_index.dimensions()); - const auto X = field_map_index.get_size(0); - const auto Y = field_map_index.get_size(1); - const auto Z = field_map_index.get_size(2); - - for (size_t kz = 0; kz < Z; kz++) { - for (size_t ky = 0; ky < Y; ky++) { - for (size_t kx = 0; kx < X; kx++) { - residual_diff_map(kx, ky,kz) = residuals_map(field_map_index(kx, ky,kz), kx, ky,kz) - - residuals_map(proposed_field_map_index(kx, ky,kz), kx, ky,kz); - - - } - } - } - - - std::vector color_map; - if (Z == 1) { - color_map = graph_cut<2>(field_map_index, proposed_field_map_index, lambda_map, - residual_diff_map); - } else { - color_map = graph_cut<3>(field_map_index, proposed_field_map_index, lambda_map, residual_diff_map); - } - - - - auto result = field_map_index; - size_t updated_voxels = 0; - for (size_t i = 0; i < field_map_index.get_number_of_elements(); i++) { - if (color_map[i] != boost::default_color_type::black_color) { - updated_voxels++; - result[i] = proposed_field_map_index[i]; - } - } - - return result; - - } - -} \ No newline at end of file diff --git a/toolboxes/fatwater/graph_cut.h b/toolboxes/fatwater/graph_cut.h deleted file mode 100644 index c6419d374..000000000 --- a/toolboxes/fatwater/graph_cut.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - - - -#include "hoNDArray.h" -namespace Gadgetron { - - - hoNDArray - update_field_map(const hoNDArray &field_map_index, const hoNDArray &proposed_field_map_index, - const hoNDArray &residuals_map, const hoNDArray &lambda_map); - -} \ No newline at end of file diff --git a/toolboxes/mri/hyper/CMRTOperator.cpp b/toolboxes/mri/hyper/CMRTOperator.cpp deleted file mode 100644 index f26121298..000000000 --- a/toolboxes/mri/hyper/CMRTOperator.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * CMRTOperator.cpp - * - * Created on: Apr 15, 2014 - * Author: u051747 - */ - -#include "CMRTOperator.h" - -namespace Gadgetron { - -CMRTOperator::CMRTOperator() { - // TODO Auto-generated constructor stub - -} - -CMRTOperator::~CMRTOperator() { - // TODO Auto-generated destructor stub -} - -} /* namespace Gadgetron */ diff --git a/toolboxes/mri/hyper/CMRTOperator.h b/toolboxes/mri/hyper/CMRTOperator.h deleted file mode 100644 index 9392994ed..000000000 --- a/toolboxes/mri/hyper/CMRTOperator.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * CMRTOperator.h - * - * Created on: Apr 15, 2014 - * Author: u051747 - */ -#pragma once - -#include "linearOperator.h" -#include "cuNDArray.h" -#include "radial_utilities.h" -#include "cuNFFT.h" -#include "../../nfft/NFFTOperator.h" -#include "cuNDFFT.h" -#include "vector_td_operators.h" - -#include "hoNDArray_fileio.h" -#include "cudaDeviceManager.h" - -#include - -namespace Gadgetron { - -template class CMRTOperator: public linearOperator > > { - typedef complext COMPLEX; -public: - CMRTOperator(): W_(5.5), alpha_(2),readout_oversampling_factor_(1){}; - virtual ~CMRTOperator(){}; - - virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate = false){ - cuNDArray projections(projection_dims); - E_.mult_MH(in,&projections); - std::vector permute_dims; - permute_dims.push_back(0); - permute_dims.push_back(2); - permute_dims.push_back(1); - permute_dims.push_back(3); - projections = permute(projections, permute_dims); - cuNDFFT::instance()->fft(&projections,0u); - - COMPLEX* proj_ptr = projections.get_data_ptr(); - std::vector proj_dim3d(projection_dims.begin(),projection_dims.end()-1); - std::vector out_dim3d({out->get_size(0),out->get_size(1),out->get_size(2)}); - COMPLEX* out_ptr = out->get_data_ptr(); - for (size_t t = 0; t< out->get_size(3); t++){ - cuNDArray proj_view(proj_dim3d,proj_ptr); - cuNDArray out_view(out_dim3d,out_ptr); - backprojections[t]->mult_MH(&proj_view,&out_view,accumulate); - proj_ptr += proj_view.get_number_of_elements(); - out_ptr += out_view.get_number_of_elements(); - } - } - - - virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate = false){ - - cuNDArray projections(projection_dims_permuted); - - COMPLEX* proj_ptr = projections.get_data_ptr(); - std::vector proj_dim3d(projection_dims.begin(),projection_dims.end()-1); - std::vector in_dim3d({in->get_size(0),in->get_size(1),in->get_size(2)}); - COMPLEX* in_ptr = in->get_data_ptr(); - for (size_t t = 0; t< in->get_size(3); t++){ - cuNDArray proj_view(proj_dim3d,proj_ptr); - cuNDArray in_view(in_dim3d,in_ptr); - backprojections[t]->mult_M(&in_view,&proj_view,accumulate); - proj_ptr += proj_view.get_number_of_elements(); - in_ptr += in_view.get_number_of_elements(); - } - - - cuNDFFT::instance()->ifft(&projections,0u); - std::vector permute_dims = {0,2,1,3}; - projections = permute(projections,permute_dims); - - - E_.mult_M(&projections,out,accumulate); - } - - - void setup( boost::shared_ptr > > traj, std::vector& dims,std::vector& projection_dims, unsigned int offset, bool golden_ratio ){ - - E_.setup( uint64d2(projection_dims[0], projection_dims[1]), - uint64d2(projection_dims[0], projection_dims[1])*size_t(2), // !! <-- alpha_ - W_ ); - E_.preprocess(*traj); - - this->projection_dims = projection_dims; - projection_dims_permuted = projection_dims; - projection_dims_permuted[1] = projection_dims[2]; - projection_dims_permuted[2] = projection_dims[1]; - - size_t ntimeframes = projection_dims.size() > 3 ? projection_dims[3] : 1; - /* - boost::shared_ptr< cuNDArray > b_dcw = compute_radial_dcw_fixed_angle_2d - ( dims[0], projection_dims[2], alpha_, 1.0f/readout_oversampling_factor_ ); - sqrt_inplace(b_dcw.get()); - - //backprojection.set_dcw(b_dcw); - */ - - size_t time_offset =offset; - backprojections.clear(); - for (size_t t = 0; t < ntimeframes; t++){ - auto backprojection = boost::make_shared>(); - backprojection->setup( uint64d2(dims[0], dims[1]), - uint64d2(dims[0], dims[1])*size_t(2), // !! <-- alpha_ - W_ ); - - boost::shared_ptr< cuNDArray > traj2; - - if (golden_ratio){ - traj2= compute_radial_trajectory_golden_ratio_2d - ( projection_dims[0], projection_dims[2],1, time_offset, GR_ORIGINAL ); - - } - else{ - traj2= compute_radial_trajectory_fixed_angle_2d - ( projection_dims[0], projection_dims[2], 1/*number of frames*/ ); - } - - - backprojection->preprocess(*traj2); - backprojections.push_back(backprojection); - time_offset += projection_dims[2]; - } - - } - - -protected: - - NFFTOperator E_; //cuNFFTOperator reconstructing the 2d projections - std::vector< boost::shared_ptr< NFFTOperator>> backprojections; //cuNFFTOperator doing the equivalent of backprojection - - std::vector projection_dims; - std::vector projection_dims_permuted; - REAL W_; - REAL readout_oversampling_factor_; - REAL alpha_; -}; - -} /* namespace Gadgetron */ - diff --git a/toolboxes/mri/hyper/CSIOperator.cpp b/toolboxes/mri/hyper/CSIOperator.cpp deleted file mode 100644 index ee033876b..000000000 --- a/toolboxes/mri/hyper/CSIOperator.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * CSIOperator.cpp - * - * Created on: Nov 10, 2014 - * Author: dch - */ - -#include "CSIOperator.h" -#include "cuNDFFT.h" -#include "cuNDArray_math.h" -#include "CSI_utils.h" - -namespace Gadgetron { - - -template CSIOperator::CSIOperator() { - // TODO Auto-generated constructor stub -} - -template CSIOperator::CSIOperator(T dtt, T dte ) : dtt_(dtt), dte_(dte) { - // TODO Auto-generated constructor stub - -} - -template CSIOperator::~CSIOperator() { - // TODO Auto-generated destructor stub -} - - -template void CSIOperator::mult_MH(cuNDArray> *in , cuNDArray> * out, bool accumulate){ - - std::vector kdim = in->get_dimensions(); - kdim[1] =frequencies.size(); //Set to number of time samples rather than number of frequencies - cuNDArray> tmp(kdim); - //senseOp->mult_MH(in,out,accumulate); - - CSI_dft(&tmp,in,&frequencies,dtt_,dte_); - senseOp->mult_MH(&tmp,out,accumulate); - //cuNDFFT::instance()->fft(&tmp,0u); //FFT along the TE dimension -} - -template void CSIOperator::set_frequencies(std::vector& freq) { - frequencies = cuNDArray(freq.size()); - cudaMemcpy(frequencies.data(), freq.data(), frequencies.get_number_of_bytes(), cudaMemcpyKind::cudaMemcpyHostToDevice); - -} - -template void CSIOperator::mult_M(cuNDArray> *in , cuNDArray> * out, bool accumulate){ - cuNDArray>* out_tmp = out; - if (accumulate) out_tmp = new cuNDArray>(out->get_dimensions()); - std::vector kdim = out->get_dimensions(); - kdim[1] =frequencies.size(); - cuNDArray> tmp(kdim); - senseOp->mult_M(in,&tmp,accumulate); - - CSI_dftH(&tmp,out_tmp,&frequencies,dtt_,dte_); - if (accumulate){ - *out += *out_tmp; - delete out_tmp; - } -} - - -template class CSIOperator; - -} /* namespace Gadgetron */ diff --git a/toolboxes/mri/hyper/CSIOperator.h b/toolboxes/mri/hyper/CSIOperator.h deleted file mode 100644 index 34878e1f1..000000000 --- a/toolboxes/mri/hyper/CSIOperator.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * CSIOperator.h - * - * Created on: Nov 10, 2014 - * Author: dch - */ - -#ifndef CSIOPERATOR_H_ -#define CSIOPERATOR_H_ - -#include "linearOperator.h" -#include "cuNDArray.h" - -namespace Gadgetron { - -template class CSIOperator: public Gadgetron::linearOperator>> { -public: - CSIOperator(); - CSIOperator(T dtt, T dte); - virtual ~CSIOperator(); - virtual void mult_M(cuNDArray>* in, cuNDArray>* out,bool accumulate ); - virtual void mult_MH(cuNDArray>* in, cuNDArray>* out,bool accumulate ); - - void set_senseOp(boost::shared_ptr>>> op){ senseOp = op;} - void set_frequencies(std::vector& freq); - - cuNDArray get_frequencies(){ - return frequencies; - } - - - T get_echotime(){ return dte_;} - T get_pointtime(){return dtt_;} - -protected: - boost::shared_ptr>>> senseOp; - T dte_; //Time between echoes - T dtt_; //Time between k-space points - cuNDArray frequencies; -}; - -} /* namespace Gadgetron */ - -#endif /* CSIOPERATOR_H_ */ diff --git a/toolboxes/mri/hyper/CSI_utils.cu b/toolboxes/mri/hyper/CSI_utils.cu deleted file mode 100644 index 4ae723cd8..000000000 --- a/toolboxes/mri/hyper/CSI_utils.cu +++ /dev/null @@ -1,177 +0,0 @@ -#include "CSI_utils.h" -#include -#include "cudaDeviceManager.h" -#include "complext.h" -#include -#include -#include "cuNDArray_math.h" -#include "cuNDArray_fileio.h" -#include -using namespace Gadgetron; - - -template static __global__ void dft_kernel(complext* __restrict__ kspace, const complext* __restrict__ tspace, T* __restrict__ frequencies, unsigned int spiral_length, unsigned int echoes, unsigned int nfreqs,T dte, T dtt){ - const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; - if (idx < spiral_length*nfreqs ){ - complext result = 0; - T frequency = frequencies[idx/spiral_length]; - T time_offset = dtt*(idx%spiral_length); - unsigned int kpoint = idx%spiral_length; - for (unsigned int i =0; i < echoes; i++){ - result += exp(complext(0,-frequency*2*CUDART_PI_F*(dte*i+time_offset)))*tspace[kpoint+i*spiral_length]; - } - kspace[idx] = result; - } -} - -template static __global__ void dftH_kernel(const complext* __restrict__ kspace, complext* __restrict__ tspace, T* __restrict__ frequencies, unsigned int spiral_length, unsigned int echoes, unsigned int nfreqs,T dte, T dtt){ - const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; - if (idx < spiral_length*echoes ){ - complext result = 0; - unsigned int kpoint = idx%spiral_length; - T timeshift = dte*(idx/spiral_length)+dtt*kpoint; - for (unsigned int i =0; i < nfreqs; i++){ - result += exp(complext(0,frequencies[i]*2*CUDART_PI_F*timeshift))*kspace[kpoint+i*spiral_length]; - } - tspace[idx] = result; - } -} - - - -template -void Gadgetron::CSI_dft(cuNDArray >* kspace, - cuNDArray >* tspace, cuNDArray* frequencies, T dtt, T dte) { - - size_t elements = kspace->get_size(0)*kspace->get_size(1); - size_t batches = kspace->get_number_of_elements()/elements; - size_t t_elements = tspace->get_size(0)*tspace->get_size(1); - int threadsPerBlock = std::min(elements,cudaDeviceManager::Instance()->max_blockdim()); - dim3 dimBlock(threadsPerBlock); - int totalBlocksPerGrid = (elements+threadsPerBlock-1)/threadsPerBlock; - dim3 dimGrid(totalBlocksPerGrid); - - std::vector dims = tspace->get_dimensions(); - if (totalBlocksPerGrid > cudaDeviceManager::Instance()->max_griddim()) - throw std::runtime_error("CSIOperator: Input dimensions too large"); - - cudaFuncSetCacheConfig(dft_kernel,cudaFuncCachePreferL1); - for (int i = 0; i< batches; i++){ - - //size_t batchSize = dimGrid.x*dimBlock.x; - - // Invoke kernel - dft_kernel<<>>(kspace->get_data_ptr()+i*elements,tspace->get_data_ptr()+i*t_elements,frequencies->data(),dims[0],dims[1], frequencies->size(),dte,dtt); - CHECK_FOR_CUDA_ERROR(); - cudaDeviceSynchronize(); - - } - - *kspace /= T(dims[1]); - -} - -template -void Gadgetron::CSI_dftH(cuNDArray >* kspace, - cuNDArray >* tspace, cuNDArray* frequencies, T dtt, T dte) { - size_t k_elements = kspace->get_size(0)*kspace->get_size(1); - size_t elements = tspace->get_size(0)*tspace->get_size(1); - - size_t batches = tspace->get_number_of_elements()/elements; - int threadsPerBlock = std::min(elements,cudaDeviceManager::Instance()->max_blockdim()); - dim3 dimBlock(threadsPerBlock); - int totalBlocksPerGrid = (elements+threadsPerBlock-1)/threadsPerBlock; - dim3 dimGrid(totalBlocksPerGrid); - - if (totalBlocksPerGrid > cudaDeviceManager::Instance()->max_griddim()) - throw std::runtime_error("CSIOperator: Input dimensions too large"); - - //size_t batchSize = dimGrid.x*dimBlock.x; - cudaFuncSetCacheConfig(dftH_kernel,cudaFuncCachePreferL1); - - std::vector dims = tspace->get_dimensions(); - - for (int i =0; i< batches; i++){ - // Invoke kernel - dftH_kernel<<>>(kspace->get_data_ptr()+i*k_elements,tspace->get_data_ptr()+i*elements,frequencies->data(),dims[0],dims[1], frequencies->size(),dte,dtt); - CHECK_FOR_CUDA_ERROR(); - } - *tspace /= T(dims[1]); -} - -template -boost::shared_ptr > > Gadgetron::calculate_frequency_calibration(cuNDArray >* time_track, cuNDArray* frequencies,cuNDArray > * csm,T dtt,T dte){ - std::vector out_dims; - out_dims.push_back(frequencies->size()); - out_dims.push_back(1); - - cuNDArray >* time2 = time_track; - if (csm){ - std::vector csm_dims = csm->get_dimensions(); - int coils = csm_dims.back(); - csm_dims.pop_back(); - - std::vector time_dims = time_track->get_dimensions(); - - if (time_dims.back() != coils) - throw std::runtime_error("Number of coils in time data does not match number of coils in CSM"); - - - time_dims.back() = time_dims.front(); - time_dims.front() = 1; - time_dims.push_back(coils); - - time2 = new cuNDArray >(time_dims, time_track->get_data_ptr()); - out_dims.push_back(coils); - } - - boost::shared_ptr > > result(new cuNDArray >(out_dims)); - clear(result.get()); - - CSI_dft(result.get(),time2,frequencies,float(0),dtt); - - if (csm) - delete time2; - return result; - - - -} - -template static __global__ void mult_freq_kernel(complext* in_out, complext* freqs, bool conjugate){ - const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; - if (conjugate) - in_out[idx] *= conj(freqs[blockIdx.y]); - else - in_out[idx] *= freqs[blockIdx.y]; - -} -template< class T> -void Gadgetron::mult_freq(cuNDArray >* in_out, cuNDArray >* freqs, bool conjugate){ - - std::vector dims = in_out->get_dimensions(); - - if (dims.back() != freqs->get_number_of_elements()){ - throw std::runtime_error("Input image dimensions do not match frequencies"); - } - - size_t elements = in_out->get_number_of_elements()/dims.back(); - int threadsPerBlock = std::min(elements,cudaDeviceManager::Instance()->max_blockdim()); - dim3 dimBlock(threadsPerBlock); - int totalBlocksPerGrid = (elements+threadsPerBlock-1)/threadsPerBlock; - dim3 dimGrid(totalBlocksPerGrid,dims.back()); - - mult_freq_kernel<<>>(in_out->get_data_ptr(),freqs->get_data_ptr(),conjugate); - - -} - - - - -template void Gadgetron::CSI_dft(cuNDArray* kspace,cuNDArray* tspace, cuNDArray* frequencies, float dtt, float dte); -template void Gadgetron::CSI_dftH(cuNDArray* kspace,cuNDArray* tspace, cuNDArray* frequencies, float dtt, float dte); - - -template boost::shared_ptr > Gadgetron::calculate_frequency_calibration(cuNDArray* time_track, cuNDArray* frequencies,cuNDArray * csm,float dtt,float dte); -template void Gadgetron::mult_freq(cuNDArray >* in_out, cuNDArray >* freqs, bool conjugate); diff --git a/toolboxes/mri/hyper/CSI_utils.h b/toolboxes/mri/hyper/CSI_utils.h deleted file mode 100644 index e8b7f716c..000000000 --- a/toolboxes/mri/hyper/CSI_utils.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * CSI_utils.h - * - * Created on: Nov 20, 2014 - * Author: dch - */ - -#pragma once - -#include "cuNDArray.h" -#include -namespace Gadgetron { - - /** - * Performs a non-cartesian discrete fourier transform (DFT) along the specified frequencies, at the specified time intervals. - * Note that this should be no used for general purpose DFTS as it will be mindnumbingly slow. - * @param kspace The output kspace - * @param tspace The input time space - * @param frequencies The frequencies on which to do DFT. - * @param dtt Time step between points in the first dimension of the tspace - * @param dte Time step between points in the second dimension of the tspace - */ - template void CSI_dft(cuNDArray >* kspace, cuNDArray >* tspace, cuNDArray* frequencies, T dtt, T dte); - /** - * Performs the adjoint of the non-cartesian discrete fourier transform. - * @param kspace The input kspace - * @param tspace The output time space - * @param frequencies Frequencies on which to do DFT. - * @param dte Time step between points in the first dimension of the tspace - * @param dtt Time step between points in the second dimension of the tspace - */ - template void CSI_dftH(cuNDArray >* kspace, cuNDArray >* tspace, cuNDArray* frequencies, T dte, T dtt); - - template boost::shared_ptr > > calculate_frequency_calibration(cuNDArray >* time_track, cuNDArray* frequencies,cuNDArray > * csm,T dtt,T dte); - - template void mult_freq(cuNDArray >* in_out, cuNDArray >* freqs, bool conjugate); -} diff --git a/toolboxes/mri/hyper/CSfreqOperator.h b/toolboxes/mri/hyper/CSfreqOperator.h deleted file mode 100644 index b0208033c..000000000 --- a/toolboxes/mri/hyper/CSfreqOperator.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * CSfreqOperator.h - * - * Created on: Dec 2, 2014 - * Author: dch - */ - -#ifndef CSFREQOPERATOR_H_ -#define CSFREQOPERATOR_H_ - -#include "linearOperator.h" -#include "cuNDArray.h" -#include "CSI_utils.h" -namespace Gadgetron{ -class CSfreqOperator : public linearOperator > { - -public: - - CSfreqOperator(){}; - CSfreqOperator(float dtt_, float dte_) : dtt(dtt_), dte(dte_){ - -} - - virtual void mult_M(cuNDArray * in, cuNDArray* out,bool accumulate){ - auto tmp_out = out; - if (accumulate) tmp_out = new cuNDArray(*out); - CSI_dftH(in,tmp_out,&freqs,dte,dtt); - if (accumulate){ - *out += *tmp_out; - delete tmp_out; - } - } - virtual void mult_MH(cuNDArray * in, cuNDArray* out,bool accumulate){ - auto tmp_out = out; - if (accumulate) tmp_out = new cuNDArray(*out); - CSI_dft(tmp_out,in,&freqs,dte,dtt); - if (accumulate){ - *out += *tmp_out; - delete tmp_out; - } - } - void set_frequencies(std::vector& freq) { - freqs = cuNDArray(freq.size()); - cudaMemcpy(freqs.data(), freq.data(), freqs.get_number_of_bytes(), cudaMemcpyKind::cudaMemcpyHostToDevice); - } - - cuNDArray freqs; - float dtt,dte; -}; -} - - -#endif /* CSFREQOPERATOR_H_ */ diff --git a/toolboxes/plplot/CMakeLists.txt b/toolboxes/plplot/CMakeLists.txt deleted file mode 100644 index 66f335257..000000000 --- a/toolboxes/plplot/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# pingvin_toolbox_plplot is a toolbox for plotting gadgetron data structures using PLplot - -include_directories(${PLPLOT_INCLUDE_DIR}) -link_directories(${PLPLOT_LIB_DIR}) - -set(header_files GtPLplot.h) -set(src_files GtPLplot.cpp) - -set(plplot_files ${header_files} ${src_files} ) - -source_group(plplot FILES ${header_files} ${src_files}) - -add_library(pingvin_toolbox_plplot SHARED - ${plplot_files} ) - -set_target_properties(pingvin_toolbox_plplot PROPERTIES VERSION ${PINGVIN_VERSION_STRING} SOVERSION ${PINGVIN_SOVERSION}) - -target_link_libraries(pingvin_toolbox_plplot - ${PLPLOT_LIBRARIES} - pingvin_toolbox_cpucore - pingvin_toolbox_log - pingvin_toolbox_cpucore_math - pingvin_toolbox_mri_core - pingvin_toolbox_cpucore_math ) - -target_include_directories(pingvin_toolbox_plplot - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}) - -install(TARGETS pingvin_toolbox_plplot - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - COMPONENT main -) - -install (FILES - ${header_files} - DESTINATION ${PINGVIN_INSTALL_INCLUDE_PATH} COMPONENT main) \ No newline at end of file diff --git a/toolboxes/plplot/GtPLplot.cpp b/toolboxes/plplot/GtPLplot.cpp deleted file mode 100644 index f74aa99b7..000000000 --- a/toolboxes/plplot/GtPLplot.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/** \file GtPLplot.cpp - \brief Implement Gt PLplot functions. - \author Hui Xue -*/ - -#include "GtPLplot.h" -#include -#include -#include - -#include "plConfig.h" -#include "plplot.h" - -namespace Gadgetron { - -// ----------------------------------------------- - -template -void findDataRange(const std::vector>& x, const std::vector>& y, T& minX, T& maxX, T& minY, - T& maxY) { - size_t n; - - maxY = Gadgetron::max(const_cast*>(&y[0])); - minY = Gadgetron::min(const_cast*>(&y[0])); - - maxX = Gadgetron::max(const_cast*>(&x[0])); - minX = Gadgetron::min(const_cast*>(&x[0])); - - for (n = 1; n < x.size(); n++) { - T v = Gadgetron::max(const_cast*>(&y[n])); - if (v > maxY) - maxY = v; - - v = Gadgetron::min(const_cast*>(&y[n])); - if (v < minY) - minY = v; - - v = Gadgetron::max(const_cast*>(&x[n])); - if (v > maxX) - maxX = v; - - v = Gadgetron::min(const_cast*>(&x[n])); - if (v < minX) - minX = v; - } -} - -void outputPlotIm(const hoNDArray& im, bool trueColor, hoNDArray& plotIm) { - size_t xsize = im.get_size(1); - size_t ysize = im.get_size(2); - - plotIm.copyFrom(im); - - if (trueColor) { - std::vector dim_order(3); - dim_order[0] = 1; - dim_order[1] = 2; - dim_order[2] = 0; - - hoNDArray plotImPermuted; - plotImPermuted.copyFrom(plotIm); - - plotIm.create(xsize, ysize, 3); - - Gadgetron::permute(plotImPermuted, plotIm, dim_order); - } else { - hoNDArray plotIm2D; - Gadgetron::sum_over_dimension(plotIm, plotIm2D, 0); - - plotIm2D.squeeze(); - - std::vector dim_order(2); - dim_order[0] = 0; - dim_order[1] = 1; - - plotIm.create(xsize, ysize); - Gadgetron::permute(plotIm2D, plotIm, dim_order); - } -} - -// 0 black(default background) -// 1 red(default foreground) -// 2 yellow -// 3 green -// 4 aquamarine -// 5 pink -// 6 wheat -// 7 grey -// 8 brown -// 9 blue -// 10 BlueViolet -// 11 cyan -// 12 turquoise -// 13 magenta -// 14 salmon -// 15 white - -void getPlotColor(size_t n, int& color) { - switch (n % 15) { - case 0: - color = 15; - break; - - case 1: - color = 2; - break; - - case 2: - color = 3; - break; - - case 3: - color = 4; - break; - - case 5: - color = 6; - break; - - case 6: - color = 7; - break; - - case 7: - color = 8; - break; - - case 8: - color = 9; - break; - - case 9: - color = 10; - break; - - case 10: - color = 11; - break; - - case 11: - color = 12; - break; - - case 12: - color = 13; - break; - - case 13: - color = 14; - break; - - case 14: - color = 1; - break; - - default: - color = 15; - } -} - -void getPlotGlyph(size_t n, std::string& gly) { - switch (n % 26) { - case 0: - gly = "#(840)"; // circle; - break; - - case 1: - gly = "#(752)"; // * - break; - - case 2: - gly = "#(225)"; // + - break; - - case 3: - gly = "#(048)"; // x - break; - - case 5: - gly = "#(729)"; // . - break; - - case 6: - gly = "#(852)"; // triangle (up) - break; - - case 7: - gly = "#(854)"; // triangle (down) - break; - - case 8: - gly = "#(853)"; // triangle (left) - break; - - case 9: - gly = "#(855)"; // triangle (right) - break; - - case 10: - gly = "#(857)"; // flag - break; - - case 11: - gly = "#(212)"; // : - break; - - case 12: - gly = "#(221)"; // < - break; - - case 13: - gly = "#(222)"; // > - break; - - case 14: - gly = "#(851)"; // square - break; - - case 15: - gly = "#(751)"; // rectangle - break; - - case 16: - gly = "#(828)"; - break; - - case 17: - gly = "#(227)"; // x - break; - - case 18: - gly = "#(229)"; // . - break; - - case 19: - gly = "#(233)"; // # - break; - - case 20: - gly = "#(850)"; // filled circle - break; - - case 21: - gly = "#(844)"; // unfilled star - break; - - case 22: - gly = "#(843)"; // unfilled diamond - break; - - case 23: - gly = "#(842)"; // unfilled triangle - break; - - case 24: - gly = "#(841)"; // big square - break; - - case 25: - gly = "#(2367)"; // . - break; - - default: - gly = "#(856)"; // star - } -} - -template -bool -plotCurves(const std::vector>& x, const std::vector>& y, const std::string& xlabel, - const std::string& ylabel, const std::string& title, const std::vector& legend, - const std::vector& symbols, size_t xsize, size_t ysize, bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, hoNDArray& plotIm) { - try { - GADGET_CHECK_RETURN_FALSE(x.size() > 0); - GADGET_CHECK_RETURN_FALSE(y.size() > 0); - GADGET_CHECK_RETURN_FALSE(x.size() == y.size()); - - T xlim[2], ylim[2]; - findDataRange(x, y, xlim[0], xlim[1], ylim[0], ylim[1]); - - return Gadgetron::plotCurves(x, y, xlabel, ylabel, title, legend, symbols, xsize, ysize, xlim, ylim, trueColor, - drawLine, lineStyple, lineWidth, plotIm); - } catch (...) { - GERROR_STREAM("Errors happened in plotCurves(...) ... "); - return false; - } - - return true; -} - -template bool plotCurves(const std::vector>& x, const std::vector>& y, - const std::string& xlabel, const std::string& ylabel, const std::string& title, - const std::vector& legend, const std::vector& symbols, - size_t xsize, size_t ysize, bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, - hoNDArray& plotIm); - -template bool -plotCurves(const std::vector>& x, const std::vector>& y, const std::string& xlabel, - const std::string& ylabel, const std::string& title, const std::vector& legend, - const std::vector& symbols, size_t xsize, size_t ysize, bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, hoNDArray& plotIm); - -template -bool plotCurves(const std::vector>& x, const std::vector>& y, - const std::string& xlabel, const std::string& ylabel, const std::string& title, - const std::vector& legend, const std::vector& symbols, - size_t xsize, size_t ysize, T xlim[2], T ylim[2], bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, - hoNDArray& plotIm) { - try { - GADGET_CHECK_RETURN_FALSE(x.size() > 0); - GADGET_CHECK_RETURN_FALSE(y.size() > 0); - GADGET_CHECK_RETURN_FALSE(x.size() == y.size()); - - T minX = xlim[0]; - T maxX = xlim[1]; - T minY = ylim[0]; - T maxY = ylim[1]; - - plsdev("mem"); - - hoNDArray im; - im.create(3, xsize, ysize); - Gadgetron::clear(im); - - plsmem(im.get_size(1), im.get_size(2), im.begin()); - - plinit(); - plfont(2); - - pladv(0); - - if (legend.size() == x.size()) { - plvpor(0.11, 0.75, 0.1, 0.9); - } else { - plvpor(0.15, 0.85, 0.1, 0.9); - } - - /*T spaceX = 0.01*(maxX - minX); - T spaceY = 0.05*(maxY - minY); - plwind(minX - spaceX, maxX + spaceX, minY - spaceY, maxY + spaceY);*/ - - plvsta(); - plwind(minX, maxX, minY, maxY); - plsmaj(0.0, 0.0); - plsmin(0.0, 0.0); - - plcol0(15); - plbox("bgcnst", 0.0, 0, "bgcnstv", 0.0, 0); - - // int mark[2], space[2]; - - // mark[0] = 4000; - // space[0] = 2500; - // plstyl(1, mark, space); - - size_t num = x.size(); - - size_t n; - - hoNDArray xd, yd; - - // draw lines - for (n = 0; n < num; n++) { - size_t N = y[n].get_size(0); - - xd.copyFrom(x[n]); - yd.copyFrom(y[n]); - - if (drawLine) { - int c; - getPlotColor(n, c); - plcol0(c); - if (lineStyple.size() > n) { - pllsty(lineStyple[n]); - plwidth(lineWidth[n]); - } else { - pllsty(1); - plwidth(2); - } - plline(N, xd.begin(), yd.begin()); - } - - std::string gly; - if (symbols.size() > n) { - gly = symbols[n]; - plstring(N, xd.begin(), yd.begin(), gly.c_str()); - } - } - - plcol0(15); - plmtex("b", 3.2, 0.5, 0.5, xlabel.c_str()); - plmtex("t", 2.0, 0.5, 0.5, title.c_str()); - plmtex("l", 5.0, 0.5, 0.5, ylabel.c_str()); - - // draw the legend - if (legend.size() == x.size()) { - std::vector opt_array(num), text_colors(num), line_colors(num), line_styles(num), - symbol_numbers(num), symbol_colors(num); - std::vector symbol_scales(num), line_widths(num), box_scales(num, 1); - - std::vector glyphs(num); - std::vector syms; - PLFLT legend_width, legend_height; - - std::vector legend_text(num); - - for (n = 0; n < num; n++) { - int c; - getPlotColor(n, c); - getPlotGlyph(n, glyphs[n]); - - opt_array[n] = PL_LEGEND_SYMBOL | PL_LEGEND_LINE; - text_colors[n] = 15; - line_colors[n] = c; - - if (lineStyple.size() > n) - line_styles[n] = lineStyple[n]; - else - line_styles[n] = 1; - - line_widths[n] = 0.4; - symbol_colors[n] = c; - symbol_scales[n] = 0.75; - symbol_numbers[n] = 1; - - if (symbols.size() > n) { - syms.push_back(symbols[n].c_str()); - } else { - syms.push_back(""); - } - legend_text[n] = legend[n].c_str(); - } - - pllegend(&legend_width, &legend_height, PL_LEGEND_BACKGROUND, - PL_POSITION_OUTSIDE | PL_POSITION_RIGHT | PL_POSITION_TOP, - 0.02, // x - 0.0, // y - 0.05, // plot_width - 0, // bg_color - 15, // bb_color - 1, // bb_style - 0, // nrow - 0, // ncolumn - num, // nlegend - &opt_array[0], - 0.05, // text_offset - 0.35, // text_scale - 1.0, // text_spacing - 0.5, // text_justification - &text_colors[0], (const char**)(&legend_text[0]), - NULL, // box_colors - NULL, // box_patterns - &box_scales[0], // box_scales - NULL, // box_line_widths - &line_colors[0], &line_styles[0], &line_widths[0], &symbol_colors[0], &symbol_scales[0], - &symbol_numbers[0], (const char**)(&syms[0])); - } - - plsmin(0.0, 1.0); - plsmaj(0.0, 1.0); - - plend(); - - outputPlotIm(im, trueColor, plotIm); - } catch (...) { - GERROR_STREAM("Errors happened in plotCurves(xlim, ylim) ... "); - return false; - } - - return true; -} - -template bool plotCurves(const std::vector>& x, const std::vector>& y, - const std::string& xlabel, const std::string& ylabel, const std::string& title, - const std::vector& legend, const std::vector& symbols, - size_t xsize, size_t ysize, float xlim[2], float ylim[2], bool trueColor, - bool drawLine, const std::vector& lineStyple, - const std::vector& lineWidth, hoNDArray& plotIm); - -template bool plotCurves(const std::vector>& x, - const std::vector>& y, const std::string& xlabel, - const std::string& ylabel, const std::string& title, - const std::vector& legend, const std::vector& symbols, - size_t xsize, size_t ysize, double xlim[2], double ylim[2], bool trueColor, - bool drawLine, const std::vector& lineStyple, - const std::vector& lineWidth, hoNDArray& plotIm); - -// --------------------------------------------------- - -template -bool plotNoiseStandardDeviation(const hoNDArray>& m, const std::vector& coilStrings, - const std::string& xlabel, const std::string& ylabel, const std::string& title, - size_t xsize, size_t ysize, bool trueColor, hoNDArray& plotIm) { - try { - size_t CHA = m.get_size(0); - GADGET_CHECK_RETURN_FALSE(coilStrings.size() == CHA); - - hoNDArray xd, yd, yd2; - - xd.create(CHA); - yd.create(CHA); - - size_t c; - for (c = 0; c < CHA; c++) { - xd(c) = c + 1; - yd(c) = std::sqrt(std::abs(m(c, c))); - } - - double maxY = Gadgetron::max(&yd); - - yd2 = yd; - std::sort(yd2.begin(), yd2.end()); - double medY = yd2(CHA / 2); - - // increase dot line to be 1 sigma ~= 33% - double medRange = 0.33; - - if (maxY < medY * (1 + medRange)) { - maxY = medY * (1 + medRange); - } - - hoNDArray im; - im.create(3, xsize, ysize); - Gadgetron::clear(im); - - plsdev("mem"); - - plsmem(im.get_size(1), im.get_size(2), im.begin()); - - plinit(); - plfont(2); - pladv(0); - plvpor(0.15, 0.75, 0.1, 0.8); - - plwind(0, CHA + 1, 0, maxY * 1.05); - - plcol0(15); - plbox("bcnst", 0.0, 0, "bcnstv", 0.0, 0); - - std::string gly; - getPlotGlyph(0, gly); // circle - plstring(CHA, xd.begin(), yd.begin(), gly.c_str()); - - // draw the median line - pllsty(1); - - double px[2], py[2]; - - px[0] = 0; - px[1] = CHA + 1; - - py[0] = medY; - py[1] = medY; - - plline(2, px, py); - - pllsty(2); - - py[0] = medY * (1 - medRange); - py[1] = medY * (1 - medRange); - - plline(2, px, py); - - py[0] = medY * (1 + medRange); - py[1] = medY * (1 + medRange); - - plline(2, px, py); - - plmtex("b", 3.2, 0.5, 0.5, xlabel.c_str()); - plmtex("t", 2.0, 0.5, 0.5, title.c_str()); - plmtex("l", 5.0, 0.5, 0.5, ylabel.c_str()); - - // draw the legend - std::vector opt_array(CHA), text_colors(CHA), line_colors(CHA), line_styles(CHA), symbol_numbers(CHA), - symbol_colors(CHA); - std::vector symbol_scales(CHA), line_widths(CHA), box_scales(CHA, 1); - - std::vector symbols(CHA); - PLFLT legend_width, legend_height; - - std::vector legend_text(CHA); - - std::vector legends(CHA); - - size_t n; - for (n = 0; n < CHA; n++) { - opt_array[n] = PL_LEGEND_SYMBOL; - text_colors[n] = 15; - line_colors[n] = 15; - line_styles[n] = (n % 8 + 1); - line_widths[n] = 0.2; - symbol_colors[n] = 15; - symbol_scales[n] = 0.75; - symbol_numbers[n] = 1; - symbols[n] = gly.c_str(); - - std::ostringstream ostr; - ostr << n + 1 << ":" << coilStrings[n]; - - legends[n] = ostr.str(); - - legend_text[n] = legends[n].c_str(); - } - - pllegend(&legend_width, &legend_height, PL_LEGEND_BACKGROUND, PL_POSITION_OUTSIDE | PL_POSITION_RIGHT, - 0.02, // x - 0.0, // y - 0.05, // plot_width - 0, // bg_color - 15, // bb_color - 1, // bb_style - 0, // nrow - 0, // ncolumn - CHA, // nlegend - &opt_array[0], - 0.05, // text_offset - 0.5, // text_scale - 1.0, // text_spacing - 0.5, // text_justification - &text_colors[0], (const char**)(&legend_text[0]), - NULL, // box_colors - NULL, // box_patterns - &box_scales[0], // box_scales - NULL, // box_line_widths - &line_colors[0], &line_styles[0], &line_widths[0], &symbol_colors[0], &symbol_scales[0], - &symbol_numbers[0], (const char**)(&symbols[0])); - - plend(); - - outputPlotIm(im, trueColor, plotIm); - } catch (...) { - GERROR_STREAM("Errors happened in plotNoiseStandardDeviation(...) ... "); - return false; - } - - return true; -} - -template bool plotNoiseStandardDeviation(const hoNDArray>& m, - const std::vector& coilStrings, - const std::string& xlabel, const std::string& ylabel, - const std::string& title, size_t xsize, size_t ysize, - bool trueColor, hoNDArray& plotIm); - -template bool plotNoiseStandardDeviation(const hoNDArray>& m, - const std::vector& coilStrings, - const std::string& xlabel, const std::string& ylabel, - const std::string& title, size_t xsize, size_t ysize, - bool trueColor, hoNDArray& plotIm); - -} // namespace Gadgetron diff --git a/toolboxes/plplot/GtPLplot.h b/toolboxes/plplot/GtPLplot.h deleted file mode 100644 index f2e78dbd6..000000000 --- a/toolboxes/plplot/GtPLplot.h +++ /dev/null @@ -1,53 +0,0 @@ -/** \file GtPLplot.h - \brief PLplot functions to draw gadgetron data - \author Hui Xue -*/ - -#ifndef GT_PLPLOT_H -#define GT_PLPLOT_H - -#include "hoNDArray.h" -#include "hoNDImage.h" - -#include "hoNDArray_elemwise.h" -#include "hoNDArray_reductions.h" -#include "hoNDArray_utils.h" - -namespace Gadgetron { -/// plot 1D hoNDArray as curves -/// x: x coordinate of 1D curve -/// y: values of 1D curve -/// xlabel, ylabel: x and y label strings -/// title: title string -/// legend: legend string for every curve, if empty, no legends will be plotted -/// xsize, ysize: the plotted image size -/// plotIm: the plotted image, if trueColor = true, [xsize ysize 3] array -/// if trueColor = false, the grey image will be generated [xsize ysize] -/// if drawLine = false, the line will be not plotted, onl glyphs -template -bool -plotCurves(const std::vector>& x, const std::vector>& y, const std::string& xlabel, - const std::string& ylabel, const std::string& title, const std::vector& legend, - const std::vector& symbols, size_t xsize, size_t ysize, bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, hoNDArray& plotIm); - -/// user can supply x/y axis limits to plot -/// xlim: xmin to xmax -/// ylim: ymin to ymax -template -bool plotCurves(const std::vector>& x, const std::vector>& y, - const std::string& xlabel, const std::string& ylabel, const std::string& title, - const std::vector& legend, const std::vector& symbols, - size_t xsize, size_t ysize, T xlim[2], T ylim[2], bool trueColor, bool drawLine, - const std::vector& lineStyple, const std::vector& lineWidth, - hoNDArray& plotIm); - -/// plot noise std -template -bool plotNoiseStandardDeviation(const hoNDArray>& m, - const std::vector& coilStrings, const std::string& xlabel, - const std::string& ylabel, const std::string& title, size_t xsize, - size_t ysize, bool trueColor, hoNDArray& plotIm); -} // namespace Gadgetron - -#endif // GT_PLPLOT_H