├── .clang-format ├── CMakeLists.txt ├── LICENSE.txt ├── cmake ├── FindACE.cmake ├── FindCULA.cmake ├── FindFFTW3.cmake ├── FindGLEW.cmake ├── FindGadgetron.cmake ├── FindIsmrmrd.cmake ├── FindNumpy.cmake ├── FindTinyXML.cmake ├── FindXSD.cmake ├── FindXalanC.cmake └── FindXercesC.cmake ├── denoise ├── CMakeLists.txt ├── denoise_Edge.cpp ├── denoise_NLM.cpp ├── denoise_NLM2D.cpp ├── denoise_NLM2DPoisson.cpp ├── denoise_NLMPoisson.cpp ├── denoise_NLM_prior.cpp ├── nonlocalMeans.cu ├── nonlocalMeans.h └── split_denoise.cpp ├── mri ├── CMakeLists.txt ├── main_fista.cpp ├── main_ncg.cpp └── main_sbc.cpp ├── operators ├── BilateralPriorOperator.h ├── CMakeLists.txt ├── accumulateOperator.h ├── cuATVPrimalDualOperator.h ├── cuATrousOperator.h ├── cuATrousWavelet.cu ├── cuATrousWavelet.h ├── cuATvOperator.h ├── cuBilateralFilter.cu ├── cuBilateralFilter.h ├── cuBilateralPriorPrimalDualOperator.h ├── cuBoxFilterOperator.cu ├── cuBoxFilterOperator.h ├── cuDCT.cu ├── cuDCT.h ├── cuDCTDerivativeOperator.h ├── cuDCTOperator.h ├── cuEdgeATrousOperator.h ├── cuEdgeWavelet.cu ├── cuEdgeWavelet.h ├── cuFFTDerivativeOperator.h ├── cuFrameletOperator.cu ├── cuFrameletOperator.h ├── cuGaussianFilterOperator.cu ├── cuGaussianFilterOperator.h ├── cuHaarWaveletOperator.cu ├── cuHaarWaveletOperator.h ├── cuPICSDualOperator.h ├── cuPartialDifferenceOperator.cu ├── cuPartialDifferenceOperator.h ├── cuSSTVPrimalDualOperator.h ├── cuScaleOperator.cu ├── cuScaleOperator.h ├── cuSmallConvOperator.cu ├── cuSmallConvOperator.h ├── cuTFFT.cpp ├── cuTFFT.h ├── cuTFFTPrimalDualOperator.h ├── cuTV4DPrimalDualOperator.h ├── cuTVPrimalDualOperator.cu ├── cuTVPrimalDualOperator.h ├── cuTVTFFT.h ├── cuTensorFrameletOperator.cu ├── cuWTVPrimalDualOperator.cu ├── cuWTVPrimalDualOperator.h ├── hoCuHaarWaveletOperator.h ├── hoCuPartialDerivativeOperator.h ├── invertibleOperator.h ├── linearToSubsetOperator.h ├── primalDualOperator.h ├── projectionSpaceOperator.h ├── subselectionOperator.h ├── subsetAccumulateOperator.h ├── subsetConverter.h └── weightingOperator.h ├── proton ├── CGhostProtonReconstruct.cpp ├── CMakeLists.txt ├── DROPProtonReconstruct.cpp ├── FilteredProton.h ├── FilteredProtonReconstruct.cpp ├── circulantPreconditioner.cpp ├── circulantPreconditioner.h ├── hdf5_utils.h ├── histogram.cu ├── histogram.h ├── hoCuParallelProjection.cu ├── hoCuParallelProjection.h ├── hoCuProtonBufferedSubsetOperator.h ├── hoCuSplineBackprojectionOperator.cu ├── hostBufferedSubsetProtonReconstruct.cpp ├── hostDROPProtonReconstruct.cpp ├── hostFilteredProtonReconstruct.cpp ├── hostProtonReconstruct.cpp ├── hostSBProtonReconstruct.cpp ├── hostSubsetProtonReconstruct.cpp ├── protonDataset.cu ├── protonDataset.h ├── protonForwardProject.cpp ├── protonPreconditioner.cu ├── protonPreconditioner.h ├── protonReconstruct.cpp ├── protonSubsetOperator.h ├── proton_kernels.cu ├── proton_kernels.h ├── proton_utils.cu ├── proton_utils.h ├── splineBackprojectionOperator.cu ├── splineBackprojectionOperator.h └── subsetProtonReconstruct.cpp ├── python ├── cps2hdf5.py ├── hnd2hdf5.py ├── hndImageReader.pyx ├── hndreader.py ├── l1shroud.py ├── readReal.py ├── varian_utils.py ├── ximImageReader.pyx └── ximreader.py ├── registration ├── CMakeLists.txt ├── Matrix.h ├── cuDemonsSolver.cu ├── cuDemonsSolver.h ├── matrix_utils.h ├── morphon.cu ├── morphon.h ├── quadratureKernels.cpp ├── quadratureKernels.h ├── register_Demons_3d.cpp ├── register_Demons_3dV2.cpp └── register_Demons_4d.cpp ├── solvers ├── ABIBBSolver.h ├── ABOCSSolver.h ├── ADMM.h ├── ADMMSolver.h ├── BILBSolver.h ├── CMakeLists.txt ├── FISTASolver.h ├── acBbSolver.h ├── cgdescentSolver.h ├── cuMLSolver.h ├── cuNCGSolver.cu ├── cuNCGSolver.h ├── cuOSMOMSolverD.cu ├── cuOSMOMSolverD.h ├── cuSARTSolver.h ├── eigenTester.h ├── hoABIBBSolver.h ├── hoCuBILBSolver.h ├── hoCuCgDescentSolver.h ├── hoCuCgSolver.h ├── hoCuGPBBSolver.h ├── hoCuNCGSolver.h ├── hoCuOSNESTSolver.h ├── hoCuOSOMSolver.h ├── hoCuSbcCgSolver.h ├── hoCuSolverUtils.h ├── hoCuTTSSolver.h ├── hoGPBBSolver.h ├── hoNCGSolver.h ├── hoOSCGPBBSolver.h ├── hoOSCGSolver.h ├── hoOSGPBBSolver.h ├── mlSolver.h ├── ncgSolver.h ├── osAHZCSolver.h ├── osCGSolver.h ├── osGPBBSolver.h ├── osLALMSolver2.h ├── osLALMSolverD.h ├── osMOMSolverD.h ├── osMOMSolverD2.h ├── osMOMSolverD3.h ├── osMOMSolverDual.h ├── osMOMSolverF.h ├── osMOMSolverL1.h ├── osMOMSolverW.h ├── osPDsolver.h ├── osSARTSolver.h ├── osSPSSolver.h ├── osWLSSolver.h ├── oscGPBBSolver.h ├── protonDROPSolver.h ├── sartSolver.h ├── solver_utils.cu ├── solver_utils.h └── subsetConverter2.h ├── test ├── CMakeLists.txt ├── tests.cpp └── waveletTest.cpp └── xray ├── CBCT_acquisition.h ├── CBCT_binning.h ├── CBCT_forwards_projection.cpp ├── CBOS_OF_reconstruct.cpp ├── CBOS_reconstruct.cpp ├── CBSubsetOperator.cpp ├── CBSubsetOperator.h ├── CBSubsetWeightOperator.h ├── CB_CGreconstruct.cpp ├── CB_OF_reconstruct.cpp ├── CB_SBreconstruct.cpp ├── CB_reconstruct.cpp ├── CMakeLists.txt ├── CTOS2_reconstruct.cpp ├── CTOS3_reconstruct.cpp ├── CTOS_reconstruct.cpp ├── CTProjectionOperator.cpp ├── CTProjectionOperator.h ├── CTStat_reconstruct.cpp ├── CTSubsetOperator.cpp ├── CTSubsetOperator.h ├── CT_acquisition.cpp ├── CT_acquisition.h ├── CT_reconstruct.cpp ├── FDK_reconstruct_3d.cpp ├── FDK_reconstruct_4d.cpp ├── compare_images.cpp ├── conebeam_projection.cu ├── conebeam_projection.h ├── convolveTest.cpp ├── ct_projection.cu ├── ct_projection.h ├── cuCBOS2_reconstruct.cpp ├── cuCBOSMOM.cpp ├── cuCBOSStat_reconstruct.cpp ├── cuCBOS_reconstruct.cpp ├── cuCB_reconstruct.cpp ├── cuCTOS_reconstruct.cpp ├── cuCT_reconstruct.cpp ├── cuConebeamProjectionOperator.cpp ├── cuConebeamProjectionOperator.h ├── cuHSTVOFSolver.h ├── denoise_TV.cpp ├── dicomCTWriter.cpp ├── dicomCTWriter.h ├── dicomWriter.cpp ├── dicomWriter.h ├── float3x3.h ├── hoCuCBOS_reconstruct.cpp ├── hoCuConebeamProjectionOperator.cpp ├── hoCuConebeamProjectionOperator.h ├── hoCuOFConebeamProjectionOperator.h ├── hoCuOFPartialDerivativeOperator.cpp ├── hoCuOFPartialDerivativeOperator.h ├── hoCuTVOFPartialDerivativeOperator.h ├── hoLinearResampleOperator.cpp ├── hoLinearResampleOperator.h ├── hoLinearResampleOperator_eigen.cpp ├── hoLinearResampleOperator_eigen.h ├── mssim.cpp ├── mssim.h ├── projection_utils.cpp └── projection_utils.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: WebKit 4 | AccessModifierOffset: -4 5 | AlignTrailingComments: true 6 | AlignConsecutiveAssignments: true 7 | AlignOperands: true 8 | 9 | AllowShortFunctionsOnASingleLine: Empty 10 | AllowShortCaseLabelsOnASingleLine: true 11 | AlwaysBreakTemplateDeclarations: MultiLine 12 | ColumnLimit: 120 13 | CompactNamespaces: true 14 | BreakBeforeBraces: Attach 15 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 16 | NamespaceIndentation: All 17 | SpaceBeforeCpp11BracedList: false 18 | ... 19 | 20 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | PROJECT(gt-tomography) 4 | 5 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) 6 | 7 | find_package(Gadgetron REQUIRED) 8 | 9 | 10 | 11 | #find_path(GADGETRON_CMAKE_MODULES FindGadgetron.cmake HINTS 12 | #$ENV{GADGETRON_HOME}/cmake 13 | #/usr/local/gadgetron/cmake) 14 | 15 | #if (NOT GADGETRON_CMAKE_MODULES) 16 | # MESSAGE(FATAL_ERROR "GADGETRON_CMAKE_MODULES cannot be found. 17 | # Try to set GADGETRON_HOME environment variable.") 18 | #endif(NOT GADGETRON_CMAKE_MODULES) 19 | 20 | 21 | include_directories( "${GADGETRON_HOME}/include/gadgetron") 22 | include_directories( "/home/dch/.local/include") 23 | link_directories("${GADGETRON_LIB_DIR}/") 24 | # build options for OpenMP support 25 | find_package(OpenMP) 26 | if (OPENMP_FOUND) 27 | message("OpenMP multithreading enabled") 28 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 29 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 30 | OPTION(USE_OPENMP "Use OpenMP" On) 31 | else (OPENMP_FOUND) 32 | message("OpenMP multithreading not supported") 33 | endif (OPENMP_FOUND) 34 | if(USE_OPENMP) 35 | ADD_DEFINITIONS(-DUSE_OMP) 36 | endif(USE_OPENMP) 37 | 38 | 39 | 40 | option(BUILDCT "Build the spiral CT recon") 41 | 42 | find_package(Boost COMPONENTS system thread program_options filesystem REQUIRED) 43 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++14 -D_MWAITXINTRIN_H_INCLUDED") 44 | find_package(CUDA 9.0 REQUIRED) 45 | 46 | #ADD_DEFINITIONS(-D__STRICT_ANSI__) 47 | 48 | #ADD_DEFINITIONS(-D_MATRIX_INTRIN_H_INCLUDED) 49 | if (CUDA_FOUND) 50 | 51 | set(CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER}) 52 | set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-gencode arch=compute_61,code=sm_61 --use_fast_math -lineinfo " ) 53 | #set(CUDA_VERBOSE_BUILD ON) 54 | 55 | # Compile kernels for compute models 1.0 and 2.0 as default for Cuda 4.1 56 | # Support compute model 3.0 from Cuda 4.2 and up 57 | # Support compute model 3.5 from Cuda 5 and up 58 | 59 | MESSAGE("Compiling with ${CUDA_NVCC_FLAGS}") 60 | endif (CUDA_FOUND) 61 | find_package(OpenMP) 62 | if (OPENMP_FOUND) 63 | set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 64 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") 65 | endif() 66 | find_package(GTest) 67 | #Add support for the default ubuntu package of gtest (which is not compiled 68 | if (NOT GTEST_FOUND) 69 | find_path(GTEST_SRC_DIR src/gtest.cc HINTS /usr/src/gtest) 70 | find_path(GTEST_INCLUDE_DIRS gtest.h HINTS /usr/include/gtest) 71 | if (GTEST_SRC_DIR AND GTEST_INCLUDE_DIRS) 72 | MESSAGE("GTest src package found. Compiling as part of Gadgetron.") 73 | add_subdirectory(${GTEST_SRC_DIR} ${CMAKE_BINARY_DIR}/gtest ) 74 | include_directories(${GTEST_INCLUDE_DIRS}) 75 | set(GTEST_FOUND 1) 76 | set(GTEST_LIBRARIES gtest gtest_main) 77 | endif (GTEST_SRC_DIR AND GTEST_INCLUDE_DIRS) 78 | endif (NOT GTEST_FOUND) 79 | 80 | INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) 81 | add_subdirectory(solvers) 82 | add_subdirectory(operators) 83 | add_subdirectory(proton) 84 | add_subdirectory(registration) 85 | add_subdirectory(denoise) 86 | #add_subdirectory(xray) 87 | add_subdirectory(test) 88 | #add_subdirectory(mri) 89 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018 David Christoffer Hansen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 4 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 5 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 6 | persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 9 | Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 12 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /cmake/FindACE.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Find the ACE client includes and library 3 | # 4 | 5 | # This module defines 6 | # ACE_INCLUDE_DIR, where to find ace.h 7 | # ACE_LIBRARIES, the libraries to link against ... !! NOT header is old !! ... 8 | # ACE_FOUND, if false, you cannot build anything that requires ACE 9 | 10 | # This is the new header... 11 | 12 | ######################################################################## 13 | ## check pkg-config for ace information, if available 14 | 15 | SET(ACE_INCLUDE_DIR_GUESS) 16 | SET(ACE_LIBRARY_DIR_GUESS) 17 | SET(ACE_LINK_FLAGS) 18 | IF(PKGCONFIG_EXECUTABLE) 19 | PKGCONFIG(ace ACE_INCLUDE_DIR_GUESS ACE_LIBRARY_DIR_GUESS ACE_LINK_FLAGS ACE_C_FLAGS) 20 | IF (NOT ACE_LINK_FLAGS) 21 | PKGCONFIG(ACE ACE_INCLUDE_DIR_GUESS ACE_LIBRARY_DIR_GUESS ACE_LINK_FLAGS ACE_C_FLAGS) 22 | ENDIF (NOT ACE_LINK_FLAGS) 23 | ADD_DEFINITIONS(${ACE_C_FLAGS}) 24 | ENDIF(PKGCONFIG_EXECUTABLE) 25 | 26 | SET(ACE_LINK_FLAGS "${ACE_LINK_FLAGS}" CACHE INTERNAL "ace link flags") 27 | 28 | ######################################################################## 29 | ## general find 30 | 31 | FIND_PATH(ACE_INCLUDE_DIR ace/ACE.h ${CMAKE_SOURCE_DIR}/../ACE_wrappers/ /usr/include /usr/local/include $ENV{ACE_ROOT} $ENV{ACE_ROOT}/include DOC "directory containing ace/*.h for ACE library") 32 | 33 | # in YARP1, config was in another directory 34 | SET(ACE_INCLUDE_CONFIG_DIR "" CACHE STRING "location of ace/config.h") 35 | MARK_AS_ADVANCED(ACE_INCLUDE_CONFIG_DIR) 36 | 37 | FIND_LIBRARY(ACE_LIBRARY NAMES ACE ace PATHS ${CMAKE_SOURCE_DIR}/../ACE_wrappers/lib/ /usr/lib /usr/local/lib $ENV{ACE_ROOT}/lib $ENV{ACE_ROOT} DOC "ACE library file") 38 | 39 | IF (WIN32 AND NOT CYGWIN) 40 | SET(CMAKE_DEBUG_POSTFIX "d") 41 | FIND_LIBRARY(ACE_DEBUG_LIBRARY NAMES ACE${CMAKE_DEBUG_POSTFIX} ace${CMAKE_DEBUG_POSTFIX} PATHS ${CMAKE_SOURCE_DIR}/../ACE_wrappers/lib/ /usr/lib /usr/local/lib $ENV{ACE_ROOT}/lib $ENV{ACE_ROOT} DOC "ACE library file (debug version)") 42 | ENDIF (WIN32 AND NOT CYGWIN) 43 | 44 | 45 | ######################################################################## 46 | ## OS-specific extra linkage 47 | 48 | # Solaris needs some extra libraries that may not have been found already 49 | IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") 50 | MESSAGE(STATUS "need to link solaris-specific libraries") 51 | # LINK_LIBRARIES(socket rt) 52 | SET(ACE_LIBRARY ${ACE_LIBRARY} socket rt nsl) 53 | ENDIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") 54 | 55 | # Windows needs some extra libraries 56 | IF (WIN32 AND NOT CYGWIN) 57 | MESSAGE(STATUS "need to link windows-specific libraries") 58 | #LINK_LIBRARIES(winmm) 59 | SET(ACE_LIBRARY ${ACE_LIBRARY} winmm) 60 | ENDIF (WIN32 AND NOT CYGWIN) 61 | 62 | 63 | ######################################################################## 64 | ## finished - now just set up flags and complain to user if necessary 65 | 66 | IF (ACE_INCLUDE_DIR AND ACE_LIBRARY) 67 | SET(ACE_FOUND TRUE) 68 | ELSE (ACE_INCLUDE_DIR AND ACE_LIBRARY) 69 | SET(ACE_FOUND FALSE) 70 | ENDIF (ACE_INCLUDE_DIR AND ACE_LIBRARY) 71 | 72 | IF (ACE_DEBUG_LIBRARY) 73 | SET(ACE_DEBUG_FOUND TRUE) 74 | ELSE (ACE_DEBUG_LIBRARY) 75 | SET(ACE_DEBUG_LIBRARY ${ACE_LIBRARY}) 76 | ENDIF (ACE_DEBUG_LIBRARY) 77 | 78 | IF (ACE_FOUND) 79 | IF (NOT Ace_FIND_QUIETLY) 80 | MESSAGE(STATUS "Found ACE library: ${ACE_LIBRARY}") 81 | MESSAGE(STATUS "Found ACE include: ${ACE_INCLUDE_DIR}") 82 | ENDIF (NOT Ace_FIND_QUIETLY) 83 | ELSE (ACE_FOUND) 84 | IF (Ace_FIND_REQUIRED) 85 | MESSAGE(FATAL_ERROR "Could not find ACE") 86 | ENDIF (Ace_FIND_REQUIRED) 87 | ENDIF (ACE_FOUND) 88 | 89 | # TSS: backwards compatibility 90 | SET(ACE_LIBRARIES ${ACE_LIBRARY}) 91 | -------------------------------------------------------------------------------- /cmake/FindCULA.cmake: -------------------------------------------------------------------------------- 1 | # - Find CULA 2 | # Find the native CULA includes and library 3 | # 4 | # CULA_FOUND - True if CULA found. 5 | # CULA_INCLUDE_DIR - where to find cula.h, etc. 6 | # CULA_LIBRARIES - List of libraries when using TinyXML. 7 | # 8 | 9 | IF( CULA_INCLUDE_DIR ) 10 | # Already in cache, be silent 11 | SET( CULA_FIND_QUIETLY TRUE ) 12 | ENDIF( CULA_INCLUDE_DIR ) 13 | 14 | FIND_PATH( CULA_INCLUDE_DIR "cula.h" 15 | PATH_SUFFIXES "cula/include" ) 16 | 17 | MESSAGE("CULA_INCLUDE_DIR = ${CULA_INCLUDE_DIR}") 18 | 19 | 20 | FIND_LIBRARY( CULA_LIBRARY 21 | NAMES "cula" 22 | PATH_SUFFIXES "cula/lib64" ) 23 | 24 | FIND_LIBRARY( CULA_LAPACK_LIBRARY 25 | NAMES "cula_lapack" 26 | PATH_SUFFIXES "cula/lib64" ) 27 | 28 | FIND_LIBRARY( CULA_CORE_LIBRARY 29 | NAMES "cula_core" 30 | PATH_SUFFIXES "cula/lib64" ) 31 | 32 | FIND_LIBRARY( CULA_LAPACK_BASIC_LIBRARY 33 | NAMES "cula_lapack_basic" 34 | PATH_SUFFIXES "cula/lib64" ) 35 | 36 | #This is version 12 of CULA 37 | if (CULA_LIBRARY) 38 | list(APPEND CULA_LIBRARIES ${CULA_LIBRARY}) 39 | endif (CULA_LIBRARY) 40 | 41 | #This is version 13 of CULA 42 | if (CULA_LAPACK_LIBRARY) 43 | list(APPEND CULA_LIBRARIES ${CULA_LAPACK_LIBRARY}) 44 | endif (CULA_LAPACK_LIBRARY) 45 | 46 | #This is version 13 of CULA 47 | if (CULA_CORE_LIBRARY) 48 | list(APPEND CULA_LIBRARIES ${CULA_CORE_LIBRARY}) 49 | endif (CULA_CORE_LIBRARY) 50 | 51 | #This is version 17 of CULA 52 | if (CULA_LAPACK_BASIC_LIBRARY) 53 | list(APPEND CULA_LIBRARIES ${CULA_LAPACK_BASIC_LIBRARY}) 54 | endif (CULA_LAPACK_BASIC_LIBRARY) 55 | 56 | MESSAGE("CULA_LIBRARIES = ${CULA_LIBRARIES}") 57 | 58 | # handle the QUIETLY and REQUIRED arguments and set CULA_FOUND to TRUE if 59 | # all listed variables are TRUE 60 | INCLUDE( "FindPackageHandleStandardArgs" ) 61 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( "CULA" DEFAULT_MSG CULA_INCLUDE_DIR CULA_LIBRARIES ) 62 | 63 | MARK_AS_ADVANCED( CULA_INCLUDE_DIR CULA_LIBRARIES ) 64 | -------------------------------------------------------------------------------- /cmake/FindFFTW3.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find FFTW3. 2 | # Usage: find_package(FFTW3 [COMPONENTS [single double long-double threads]]) 3 | # 4 | # Variables used by this module: 5 | # FFTW3_ROOT_DIR - FFTW3 root directory 6 | # Variables defined by this module: 7 | # FFTW3_FOUND - system has FFTW3 8 | # FFTW3_INCLUDE_DIR - the FFTW3 include directory (cached) 9 | # FFTW3_INCLUDE_DIRS - the FFTW3 include directories 10 | # (identical to FFTW3_INCLUDE_DIR) 11 | # FFTW3[FL]?_LIBRARY - the FFTW3 library - double, single(F), 12 | # long-double(L) precision (cached) 13 | # FFTW3[FL]?_THREADS_LIBRARY - the threaded FFTW3 library - double, single(F), 14 | # long-double(L) precision (cached) 15 | # FFTW3_LIBRARIES - list of all FFTW3 libraries found 16 | 17 | # Copyright (C) 2009-2010 18 | # ASTRON (Netherlands Institute for Radio Astronomy) 19 | # P.O.Box 2, 7990 AA Dwingeloo, The Netherlands 20 | # 21 | # This file is part of the LOFAR software suite. 22 | # The LOFAR software suite is free software: you can redistribute it and/or 23 | # modify it under the terms of the GNU General Public License as published 24 | # by the Free Software Foundation, either version 3 of the License, or 25 | # (at your option) any later version. 26 | # 27 | # The LOFAR software suite is distributed in the hope that it will be useful, 28 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 29 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 | # GNU General Public License for more details. 31 | # 32 | # You should have received a copy of the GNU General Public License along 33 | # with the LOFAR software suite. If not, see . 34 | # 35 | # $Id: FindFFTW3.cmake 15918 2010-06-25 11:12:42Z loose $ 36 | 37 | # Use double precision by default. 38 | if(FFTW3_FIND_COMPONENTS MATCHES "^$") 39 | set(_components double) 40 | else() 41 | set(_components ${FFTW3_FIND_COMPONENTS}) 42 | endif() 43 | 44 | # Loop over each component. 45 | set(_libraries) 46 | foreach(_comp ${_components}) 47 | if(_comp STREQUAL "single") 48 | list(APPEND _libraries fftw3f) 49 | elseif(_comp STREQUAL "double") 50 | list(APPEND _libraries fftw3) 51 | elseif(_comp STREQUAL "long-double") 52 | list(APPEND _libraries fftw3l) 53 | elseif(_comp STREQUAL "threads") 54 | set(_use_threads ON) 55 | else(_comp STREQUAL "single") 56 | message(FATAL_ERROR "FindFFTW3: unknown component `${_comp}' specified. " 57 | "Valid components are `single', `double', `long-double', and `threads'.") 58 | endif(_comp STREQUAL "single") 59 | endforeach(_comp ${_components}) 60 | 61 | # If using threads, we need to link against threaded libraries as well. 62 | if(_use_threads) 63 | set(_thread_libs) 64 | foreach(_lib ${_libraries}) 65 | list(APPEND _thread_libs ${_lib}_threads) 66 | endforeach(_lib ${_libraries}) 67 | set(_libraries ${_thread_libs} ${_libraries}) 68 | endif(_use_threads) 69 | 70 | # Keep a list of variable names that we need to pass on to 71 | # find_package_handle_standard_args(). 72 | set(_check_list) 73 | 74 | # Search for all requested libraries. 75 | foreach(_lib ${_libraries}) 76 | string(TOUPPER ${_lib} _LIB) 77 | find_library(${_LIB}_LIBRARY ${_lib} 78 | HINTS ${FFTW3_ROOT_DIR} PATH_SUFFIXES lib) 79 | mark_as_advanced(${_LIB}_LIBRARY) 80 | list(APPEND FFTW3_LIBRARIES ${${_LIB}_LIBRARY}) 81 | list(APPEND _check_list ${_LIB}_LIBRARY) 82 | endforeach(_lib ${_libraries}) 83 | 84 | # Search for the header file. 85 | find_path(FFTW3_INCLUDE_DIR fftw3.h 86 | HINTS ${FFTW3_ROOT_DIR} PATH_SUFFIXES include) 87 | mark_as_advanced(FFTW3_INCLUDE_DIR) 88 | list(APPEND _check_list FFTW3_INCLUDE_DIR) 89 | 90 | # Handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if 91 | # all listed variables are TRUE 92 | include(FindPackageHandleStandardArgs) 93 | find_package_handle_standard_args(FFTW3 DEFAULT_MSG ${_check_list}) 94 | -------------------------------------------------------------------------------- /cmake/FindGLEW.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find GLEW 2 | # Once done this will define 3 | # 4 | # GLEW_FOUND - system has GLEW 5 | # GLEW_INCLUDE_DIR - the GLEW include directory 6 | # GLEW_LIBRARY_DIR - where the libraries are 7 | # GLEW_LIBRARY - Link these to use GLEW 8 | # 9 | 10 | IF (GLEW_INCLUDE_DIR) 11 | # Already in cache, be silent 12 | SET(GLEW_FIND_QUIETLY TRUE) 13 | ENDIF (GLEW_INCLUDE_DIR) 14 | 15 | if( WIN32 ) 16 | if( MSVC80 ) 17 | set( COMPILER_PATH "C:/Program\ Files/Microsoft\ Visual\ Studio\ 8/VC" ) 18 | endif( MSVC80 ) 19 | if( MSVC71 ) 20 | set( COMPILER_PATH "C:/Program\ Files/Microsoft\ Visual\ Studio\ .NET\ 2003/Vc7" ) 21 | endif( MSVC71 ) 22 | FIND_PATH( GLEW_INCLUDE_DIR gl/glew.h gl/wglew.h 23 | PATHS c:/glew/include ${COMPILER_PATH}/PlatformSDK/Include ) 24 | SET( GLEW_NAMES glew32 ) 25 | FIND_LIBRARY( GLEW_LIBRARY 26 | NAMES ${GLEW_NAMES} 27 | PATHS c:/glew/lib ${COMPILER_PATH}/PlatformSDK/Lib ) 28 | else( WIN32 ) 29 | FIND_PATH( GLEW_INCLUDE_DIR glew.h wglew.h 30 | PATHS /usr/local/include /usr/include 31 | PATH_SUFFIXES gl/ GL/ ) 32 | SET( GLEW_NAMES glew GLEW ) 33 | FIND_LIBRARY( GLEW_LIBRARY 34 | NAMES ${GLEW_NAMES} 35 | PATHS /usr/lib /usr/local/lib ) 36 | endif( WIN32 ) 37 | 38 | GET_FILENAME_COMPONENT( GLEW_LIBRARY_DIR ${GLEW_LIBRARY} PATH ) 39 | 40 | IF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) 41 | SET(GLEW_FOUND TRUE) 42 | SET( GLEW_LIBRARY_DIR ${GLEW_LIBRARY} ) 43 | ELSE (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) 44 | SET( GLEW_FOUND FALSE ) 45 | SET( GLEW_LIBRARY_DIR ) 46 | ENDIF (GLEW_INCLUDE_DIR AND GLEW_LIBRARY) 47 | 48 | MARK_AS_ADVANCED( 49 | GLEW_LIBRARY 50 | GLEW_INCLUDE_DIR 51 | ) 52 | -------------------------------------------------------------------------------- /cmake/FindGadgetron.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Find the Gadgetron Installation 3 | # 4 | 5 | # This module defines 6 | # GADGETRON_INCLUDE_DIR, where to finds Gadget.h 7 | # GADGETRON_HOME, Gadgetron Root Dir 8 | # GADGETRON_LIB_DIR, This is where all the installed gadgetron libraries live 9 | # GADGETRON_FOUND, if false, you cannot build anything that requires ACE 10 | 11 | # Keep a list of variable names that we need to pass on to 12 | # find_package_handle_standard_args(). 13 | set(_check_list) 14 | 15 | # Search for the header file. 16 | find_path(GADGETRON_HOME include/gadgetron/Gadget.h 17 | HINTS $ENV{GADGETRON_HOME} /usr/local/gadgetron /usr/gadgetron) 18 | mark_as_advanced(GADGETRON_HOME) 19 | list(APPEND _check_list GADGETRON_HOME) 20 | 21 | SET(GADGETRON_INCLUDE_DIR ${GADGETRON_HOME}/include/gadgetron) 22 | mark_as_advanced(GADGETRON_INCLUDE_DIR) 23 | list(APPEND _check_list GADGETRON_INCLUDE_DIR) 24 | 25 | SET(GADGETRON_LIB_DIR ${GADGETRON_HOME}/lib) 26 | mark_as_advanced(GADGETRON_LIB_DIR) 27 | list(APPEND _check_list GADGETRON_LIB_DIR) 28 | 29 | # Handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if 30 | # all listed variables are TRUE 31 | include(FindPackageHandleStandardArgs) 32 | find_package_handle_standard_args(Gadgetron DEFAULT_MSG ${_check_list}) 33 | 34 | # If Cuda is detected on the system some header files will be needed 35 | # -- whether Cuda is used or not -- 36 | 37 | find_package(CUDA) 38 | if (CUDA_FOUND) 39 | include_directories( ${CUDA_INCLUDE_DIRS} ) 40 | endif (CUDA_FOUND) 41 | -------------------------------------------------------------------------------- /cmake/FindIsmrmrd.cmake: -------------------------------------------------------------------------------- 1 | # - Find ISMRMRRD 2 | # ISMRMRD_FOUND - True if ISMRMRD found. 3 | # ISMRMRD_INCLUDE_DIR - where to find ismrmrd.h, etc. 4 | # ISMRMRD_LIBRARIES - libismrmrd.so. 5 | # ISMRMRD_XSD_LIBRARIES - libismrmrd.so. 6 | # ISMRMRD_SCHEMA_DIR - Where to find ismrmrd.xsd 7 | 8 | FIND_PATH( ISMRMRD_INCLUDE_DIR ismrmrd.h PATHS /usr/local/ /usr/include /usr/local/include PATH_SUFFIXES ismrmrd ismrmrd/include) 9 | FIND_PATH( ISMRMRD_SCHEMA_DIR ismrmrd.xsd PATHS /usr/local/ /usr/include /usr/local/include PATH_SUFFIXES ismrmrd ismrmrd/schema) 10 | 11 | FIND_LIBRARY( ISMRMRD_LIBRARIES 12 | NAMES "ismrmrd" 13 | PATHS /usr/local/lib ${ISMRMRD_INCLUDE_DIR}/../lib /usr/lib ) 14 | 15 | FIND_LIBRARY( ISMRMRD_XSD_LIBRARIES 16 | NAMES "ismrmrd_xsd" 17 | PATHS /usr/local/lib ${ISMRMRD_INCLUDE_DIR}/../lib /usr/lib ) 18 | 19 | INCLUDE( "FindPackageHandleStandardArgs" ) 20 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( "Ismrmrd" DEFAULT_MSG ISMRMRD_INCLUDE_DIR ISMRMRD_LIBRARIES ISMRMRD_SCHEMA_DIR) 21 | 22 | MARK_AS_ADVANCED( ISMRMRD_INCLUDE_DIR ISMRMRD_LIBRARIES ISMRMRD_SCHEMA_DIR) 23 | -------------------------------------------------------------------------------- /cmake/FindNumpy.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # $Id: $ 3 | # 4 | # Author(s): Anton Deguet 5 | # Created on: 2010-01-20 6 | # 7 | # (C) Copyright 2010 Johns Hopkins University (JHU), All Rights 8 | # Reserved. 9 | # 10 | # --- begin cisst license - do not edit --- 11 | # 12 | # This software is provided "as is" under an open source license, with 13 | # no warranty. The complete license can be found in license.txt and 14 | # http://www.cisst.org/cisst/license.txt. 15 | # 16 | # --- end cisst license --- 17 | # 18 | # File based on FindNUMARRAY distributed with ITK 3.4 (see itk.org) 19 | # 20 | # Main modifications: 21 | # - use Numpy instead of Numarray for all naming 22 | # - added path for Python 2.5 and 2.6 23 | # - renamed python script generated (det_npp became determineNumpyPath) 24 | # - use lower case for CMake commands and keywords 25 | # - updated python script to use get_include, not get_numpy_include which is now deprecated 26 | # 27 | # --- 28 | # 29 | # Try to find numpy python package 30 | # Once done this will define 31 | # 32 | # PYTHON_NUMPY_FOUND - system has numpy development package and it should be used 33 | # PYTHON_NUMPY_INCLUDE_DIR - directory where the arrayobject.h header file can be found 34 | # 35 | # 36 | if(PYTHON_EXECUTABLE) 37 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/determineNumpyPath.py "try: import numpy; print numpy.get_include()\nexcept: pass\n") 38 | exec_program("${PYTHON_EXECUTABLE}" 39 | ARGS "\"${CMAKE_CURRENT_BINARY_DIR}/determineNumpyPath.py\"" 40 | OUTPUT_VARIABLE NUMPY_PATH 41 | ) 42 | endif(PYTHON_EXECUTABLE) 43 | 44 | find_path(PYTHON_NUMPY_INCLUDE_DIR arrayobject.h 45 | "${NUMPY_PATH}/numpy/" 46 | "${PYTHON_INCLUDE_PATH}/numpy/" 47 | /usr/include/python2.6/numpy/ 48 | /usr/include/python2.5/numpy/ 49 | /usr/include/python2.4/numpy/ 50 | /usr/include/python2.3/numpy/ 51 | /usr/include/numpy/ 52 | DOC "Directory where the arrayobject.h header file can be found. This file is part of the numpy package" 53 | ) 54 | 55 | if(PYTHON_NUMPY_INCLUDE_DIR) 56 | set(PYTHON_NUMPY_FOUND 1 CACHE INTERNAL "Python numpy development package is available") 57 | endif(PYTHON_NUMPY_INCLUDE_DIR) 58 | 59 | -------------------------------------------------------------------------------- /cmake/FindTinyXML.cmake: -------------------------------------------------------------------------------- 1 | # - Find TinyXML 2 | # Find the native TinyXML includes and library 3 | # 4 | # TINYXML_FOUND - True if TinyXML found. 5 | # TINYXML_INCLUDE_DIR - where to find tinyxml.h, etc. 6 | # TINYXML_LIBRARIES - List of libraries when using TinyXML. 7 | # 8 | 9 | IF( TINYXML_INCLUDE_DIR ) 10 | # Already in cache, be silent 11 | SET( TinyXML_FIND_QUIETLY TRUE ) 12 | ENDIF( TINYXML_INCLUDE_DIR ) 13 | 14 | FIND_PATH( TINYXML_INCLUDE_DIR "tinyxml.h" 15 | PATH_SUFFIXES "tinyxml" ) 16 | 17 | FIND_LIBRARY( TINYXML_LIBRARIES 18 | NAMES "tinyxml" 19 | PATH_SUFFIXES "tinyxml" ) 20 | 21 | # handle the QUIETLY and REQUIRED arguments and set TINYXML_FOUND to TRUE if 22 | # all listed variables are TRUE 23 | INCLUDE( "FindPackageHandleStandardArgs" ) 24 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( "TinyXML" DEFAULT_MSG TINYXML_INCLUDE_DIR TINYXML_LIBRARIES ) 25 | 26 | MARK_AS_ADVANCED( TINYXML_INCLUDE_DIR TINYXML_LIBRARIES ) 27 | -------------------------------------------------------------------------------- /cmake/FindXSD.cmake: -------------------------------------------------------------------------------- 1 | # - Find CodeSource Xsd 2 | # This module can be used to find Xsd and it's include path 3 | # Variables: 4 | # XSD_EXECUTABLE 5 | # XSD_INCLUDE_DIR 6 | # XSD_FOUND 7 | 8 | SET(XSD_FOUND FALSE) 9 | 10 | if(WIN32) 11 | SET(__XSD_NAME xsd.exe) 12 | else(WIN32) 13 | SET(__XSD_NAME xsdcxx xsd) 14 | endif(WIN32) 15 | 16 | if(XSD_INCLUDE_DIR) 17 | #in cache already 18 | SET(XSD_FOUND TRUE) 19 | else(XSD_INCLUDE_DIR) 20 | find_program(XSD_EXECUTABLE NAMES ${__XSD_NAME} 21 | PATHS 22 | ${XSD_DIR}/bin 23 | ) 24 | 25 | if(XSD_EXECUTABLE) 26 | SET(XSD_FOUND TRUE) 27 | else(XSD_EXECUTABLE) 28 | SET(XSD_EXECUTABLE "xsd-NOTFOUND" CACHE FILE "xsd executable path") 29 | endif(XSD_EXECUTABLE) 30 | 31 | find_path(XSD_INCLUDE_DIR NAMES xsd 32 | PATHS 33 | ${XSD_DIR}/include 34 | /usr/include 35 | /usr/local/include 36 | ) 37 | 38 | if(XSD_INCLUDE_DIR) 39 | SET(XSD_FOUND TRUE) 40 | else(XSD_INCLUDE_DIR) 41 | SET(XSD_INCLUDE_DIR "xsd-include-NOTFOUND" CACHE PATH "xsd include path") 42 | endif(XSD_INCLUDE_DIR) 43 | endif(XSD_INCLUDE_DIR) 44 | 45 | FUNCTION(XSD_EXTRACT_OPTIONS _xsd_files _xsd_options) 46 | foreach(current_arg ${ARGN}) 47 | IF(${current_arg} STREQUAL "OPTIONS") 48 | SET(_XSD_DOING_OPTIONS TRUE) 49 | else(${current_arg} STREQUAL "OPTIONS") 50 | if(_XSD_DOING_OPTIONS) 51 | SET(_xsd_options_p ${_xsd_options_p} ${current_arg}) 52 | else(_XSD_DOING_OPTIONS) 53 | SET(_xsd_files_p ${_xsd_files_p} ${current_arg}) 54 | endif(_XSD_DOING_OPTIONS) 55 | endif(${current_arg} STREQUAL "OPTIONS") 56 | endforeach(current_arg) 57 | SET(${_xsd_files} ${_xsd_files_p} PARENT_SCOPE) 58 | SET(${_xsd_options} ${_xsd_options_p} PARENT_SCOPE) 59 | ENDFUNCTION(XSD_EXTRACT_OPTIONS) 60 | 61 | 62 | FUNCTION(WRAP_XSD XSD_SRCS XSD_INCLUDES OUT_PATH) 63 | SET(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src/xsd) 64 | FILE(MAKE_DIRECTORY ${OUTPUT_DIR}) 65 | SET(${XSD_INCLUDES} ${OUTPUT_DIR} PARENT_SCOPE) 66 | XSD_EXTRACT_OPTIONS(xsd_files xsd_options ${ARGN}) 67 | FOREACH(it ${xsd_files}) 68 | STRING(REGEX REPLACE ".*/" "" BARE_XSD "${it}" ) 69 | STRING(REGEX REPLACE ".xsd" ".cxx" SOURCE "${BARE_XSD}" ) 70 | STRING(REGEX REPLACE ".xsd" ".hxx" HEADER "${BARE_XSD}" ) 71 | CONFIGURE_FILE(${it} ${OUT_PATH}/${BARE_XSD} COPY_ONLY) 72 | SET(SOURCE ${OUTPUT_DIR}/${SOURCE}) 73 | SET(HEADER ${OUTPUT_DIR}/${HEADER}) 74 | ADD_CUSTOM_COMMAND(OUTPUT ${SOURCE} ${HEADER} 75 | COMMAND ${XSD_EXECUTABLE} ${xsd_options} "--output-dir" ${OUTPUT_DIR} ${OUT_PATH}/${BARE_XSD} 76 | DEPENDS ${it} 77 | VERBATIM 78 | ) 79 | set_source_files_properties(${HEADER} PROPERTIES GENERATED TRUE) 80 | set_source_files_properties(${SOURCE} PROPERTIES GENERATED TRUE) 81 | SET(_XSD_SRCS ${_XSD_SRCS} ${SOURCE} ${HEADER}) 82 | ENDFOREACH(it) 83 | SET(${XSD_SRCS} ${_XSD_SRCS} PARENT_SCOPE) 84 | ENDFUNCTION(WRAP_XSD) 85 | 86 | -------------------------------------------------------------------------------- /cmake/FindXalanC.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find XalanC 2 | # Once done this will define 3 | # 4 | # XALANC_FOUND - System has XalanC 5 | # XALANC_INCLUDE_DIR - The XalanC include directory 6 | # XALANC_LIBRARY_DIR - The XalanC library dir 7 | # XALANC_LIBRARIES - The libraries needed to use XalanC 8 | # XALANC_DEFINITIONS - Compiler switches required for using XalanC 9 | 10 | # Copyright (c) 2009, Helio Chissini de Castro, 11 | # 12 | # Redistribution and use is allowed according to the terms of the BSD license. 13 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 14 | 15 | 16 | IF (XALANC_INCLUDE_DIR AND XALANC_LIBRARIES) 17 | # in cache already 18 | SET(XalanC_FIND_QUIETLY TRUE) 19 | ENDIF (XALANC_INCLUDE_DIR AND XALANC_LIBRARIES) 20 | 21 | 22 | FIND_PATH(XALANC_INCLUDE_DIR DOMSupport/DOMServices.hpp 23 | PATHS 24 | /usr/local/include/xalanc 25 | /usr/include/xalanc 26 | PATH_SUFFIXES 27 | xalanc 28 | ) 29 | 30 | FIND_LIBRARY(XALANC_LIBRARIES NAMES xalan-c xalanMsg) 31 | 32 | INCLUDE(FindPackageHandleStandardArgs) 33 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(XalanC DEFAULT_MSG XALANC_LIBRARIES XALANC_INCLUDE_DIR) 34 | 35 | MARK_AS_ADVANCED(XALANC_INCLUDE_DIR XALANC_LIBRARIES XALANC_LIBRARY_DIR) 36 | -------------------------------------------------------------------------------- /cmake/FindXercesC.cmake: -------------------------------------------------------------------------------- 1 | # This module defines 2 | # XERCESC_INCLUDE_DIR, where to find ptlib.h, etc. 3 | # XERCESC_LIBRARIES, the libraries to link against to use pwlib. 4 | # XERCESC_FOUND, If false, don't try to use pwlib. 5 | 6 | FIND_PATH(XERCESC_INCLUDE_DIR xercesc/dom/DOM.hpp 7 | "[HKEY_CURRENT_USER\\software\\xerces-c\\src]" 8 | "[HKEY_CURRENT_USER\\xerces-c\\src]" 9 | $ENV{XERCESCROOT}/src/ 10 | /usr/local/include 11 | /usr/include 12 | ) 13 | 14 | FIND_LIBRARY(XERCESC_LIBRARIES 15 | NAMES 16 | xerces-c 17 | PATHS 18 | "[HKEY_CURRENT_USER\\software\\xerces-c\\lib]" 19 | "[HKEY_CURRENT_USER\\xerces-c\\lib]" 20 | $ENV{XERCESCROOT}/lib 21 | /usr/local/lib 22 | /usr/lib 23 | ) 24 | 25 | # if the include a the library are found then we have it 26 | IF(XERCESC_INCLUDE_DIR) 27 | IF(XERCESC_LIBRARIES) 28 | SET( XERCESC_FOUND "YES" ) 29 | ENDIF(XERCESC_LIBRARIES) 30 | ENDIF(XERCESC_INCLUDE_DIR) 31 | 32 | 33 | 34 | MARK_AS_ADVANCED( 35 | XERCESC_INCLUDE_DIR 36 | XERCESC_LIBRARIES 37 | ) -------------------------------------------------------------------------------- /denoise/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CUDA_INCLUDE_DIRS} 3 | ${Boost_INCLUDE_DIR} 4 | ${GADGETRON_INCLUDE_DIR} 5 | ${CMAKE_SOURCE_DIR}/solvers 6 | ${CMAKE_SOURCE_DIR}/operators 7 | ${CMAKE_SOURCE_DIR}/proton 8 | ) 9 | 10 | cuda_add_library(denoise_kernels SHARED 11 | nonlocalMeans.cu 12 | ) 13 | 14 | target_link_libraries(denoise_kernels gadgetron_toolbox_gpucore gadgetron_toolbox_gpunfft gadgetron_toolbox_gpucore gadgetron_toolbox_gpufft gadgetron_toolbox_gpureg ${CUDA_LIBRARIES}) 15 | 16 | 17 | add_executable(split_denoise split_denoise.cpp) 18 | target_link_libraries(split_denoise tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 19 | 20 | add_executable(denoise_NLM denoise_NLM.cpp) 21 | target_link_libraries(denoise_NLM denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 22 | 23 | add_executable(denoise_NLM_prior denoise_NLM_prior.cpp) 24 | target_link_libraries(denoise_NLM_prior denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 25 | 26 | 27 | add_executable(denoise_NLMPoisson denoise_NLMPoisson.cpp) 28 | target_link_libraries(denoise_NLMPoisson denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 29 | 30 | 31 | add_executable(denoise_NLM2D denoise_NLM2D.cpp) 32 | target_link_libraries(denoise_NLM2D denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 33 | 34 | 35 | add_executable(denoise_NLM2DPoisson denoise_NLM2DPoisson.cpp) 36 | target_link_libraries(denoise_NLM2DPoisson denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 37 | 38 | 39 | 40 | add_executable(denoise_Edge denoise_Edge.cpp) 41 | target_link_libraries(denoise_Edge denoise_kernels tomography_operators tomography_solvers gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpuoperators gadgetron_toolbox_log gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_cpureg gadgetron_toolbox_gpucore gadgetron_toolbox_hostutils ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 42 | -------------------------------------------------------------------------------- /denoise/denoise_NLM.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * split_denoise.cpp 3 | 4 | * 5 | * Created on: Dec 10, 2015 6 | * Author: dch 7 | */ 8 | 9 | 10 | #include "hoNDArray_fileio.h" 11 | #include "hoCuNDArray_math.h" 12 | #include "vector_td_utilities.h" 13 | #include "hoNDArray_utils.h" 14 | #include "GPUTimer.h" 15 | #include "cuATrousOperator.h" 16 | #include "cuEdgeATrousOperator.h" 17 | #include "cuSbCgSolver.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "subsetAccumulateOperator.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "cuSolverUtils.h" 30 | #include "osPDsolver.h" 31 | #include "osLALMSolver.h" 32 | #include "osLALMSolver2.h" 33 | #include "cuATrousOperator.h" 34 | #include "hdf5_utils.h" 35 | #include "cuEdgeATrousOperator.h" 36 | #include "cuDCTOperator.h" 37 | #include "cuDCTDerivativeOperator.h" 38 | #include "weightingOperator.h" 39 | #include "hoNDArray_math.h" 40 | #include "cuNCGSolver.h" 41 | #include "accumulateOperator.h" 42 | #include "subselectionOperator.h" 43 | #include "subsetConverter.h" 44 | #include "nonlocalMeans.h" 45 | using namespace std; 46 | using namespace Gadgetron; 47 | using namespace std; 48 | 49 | namespace po = boost::program_options; 50 | int main(int argc, char** argv){ 51 | 52 | po::options_description desc("Allowed options"); 53 | unsigned int iterations; 54 | int device; 55 | float noise; 56 | string outputFile; 57 | desc.add_options() 58 | ("help", "produce help message") 59 | ("input,a", po::value(), "Input filename") 60 | ("output,f", po::value(&outputFile)->default_value("denoised.real"), "Output filename") 61 | ("device",po::value(&device)->default_value(0),"Number of the device to use (0 indexed)") 62 | ("noise",po::value(&noise)->default_value(1),"noise level") 63 | ("block","Use blockwise algorithm") 64 | 65 | ; 66 | 67 | po::variables_map vm; 68 | po::store(po::parse_command_line(argc, argv, desc), vm); 69 | po::notify(vm); 70 | 71 | if (vm.count("help")) { 72 | cout << desc << "\n"; 73 | return 1; 74 | } 75 | 76 | std::stringstream command_line_string; 77 | std::cout << "Command line options:" << std::endl; 78 | for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it){ 79 | boost::any a = it->second.value(); 80 | command_line_string << it->first << ": "; 81 | if (a.type() == typeid(std::string)) command_line_string << it->second.as(); 82 | else if (a.type() == typeid(int)) command_line_string << it->second.as(); 83 | else if (a.type() == typeid(unsigned int)) command_line_string << it->second.as(); 84 | else if (a.type() == typeid(float)) command_line_string << it->second.as(); 85 | else command_line_string << "Unknown type" << std::endl; 86 | command_line_string << std::endl; 87 | } 88 | std::cout << command_line_string.str(); 89 | 90 | cudaSetDevice(device); 91 | cudaDeviceReset(); 92 | 93 | string filename = vm["input"].as(); 94 | 95 | auto hoInput = read_nd_array(filename.c_str()); 96 | 97 | 98 | auto input = cuNDArray(*hoInput); 99 | 100 | auto output = input; 101 | if (vm.count("block")) 102 | nonlocal_means_block(&input,&output,noise); 103 | else 104 | nonlocal_means(&input,&output,noise); 105 | 106 | write_nd_array(&output,outputFile); 107 | 108 | } 109 | 110 | -------------------------------------------------------------------------------- /denoise/denoise_NLMPoisson.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * split_denoise.cpp 3 | 4 | * 5 | * Created on: Dec 10, 2015 6 | * Author: dch 7 | */ 8 | 9 | 10 | #include "hoNDArray_fileio.h" 11 | #include "hoCuNDArray_math.h" 12 | #include "vector_td_utilities.h" 13 | #include "hoNDArray_utils.h" 14 | #include "GPUTimer.h" 15 | #include "cuATrousOperator.h" 16 | #include "cuEdgeATrousOperator.h" 17 | #include "cuSbCgSolver.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "subsetAccumulateOperator.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "cuSolverUtils.h" 30 | #include "osPDsolver.h" 31 | #include "osLALMSolver.h" 32 | #include "osLALMSolver2.h" 33 | #include "cuATrousOperator.h" 34 | #include "hdf5_utils.h" 35 | #include "cuEdgeATrousOperator.h" 36 | #include "cuDCTOperator.h" 37 | #include "cuDCTDerivativeOperator.h" 38 | #include "weightingOperator.h" 39 | #include "hoNDArray_math.h" 40 | #include "cuNCGSolver.h" 41 | #include "accumulateOperator.h" 42 | #include "subselectionOperator.h" 43 | #include "subsetConverter.h" 44 | #include "nonlocalMeans.h" 45 | using namespace std; 46 | using namespace Gadgetron; 47 | using namespace std; 48 | 49 | namespace po = boost::program_options; 50 | int main(int argc, char** argv){ 51 | 52 | po::options_description desc("Allowed options"); 53 | unsigned int iterations; 54 | int device; 55 | float noise; 56 | string outputFile; 57 | desc.add_options() 58 | ("help", "produce help message") 59 | ("input,a", po::value(), "Input filename") 60 | ("output,f", po::value(&outputFile)->default_value("denoised.real"), "Output filename") 61 | ("device",po::value(&device)->default_value(0),"Number of the device to use (0 indexed)") 62 | ("noise",po::value(&noise)->default_value(1),"noise level") 63 | 64 | ; 65 | 66 | po::variables_map vm; 67 | po::store(po::parse_command_line(argc, argv, desc), vm); 68 | po::notify(vm); 69 | 70 | if (vm.count("help")) { 71 | cout << desc << "\n"; 72 | return 1; 73 | } 74 | 75 | std::stringstream command_line_string; 76 | std::cout << "Command line options:" << std::endl; 77 | for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it){ 78 | boost::any a = it->second.value(); 79 | command_line_string << it->first << ": "; 80 | if (a.type() == typeid(std::string)) command_line_string << it->second.as(); 81 | else if (a.type() == typeid(int)) command_line_string << it->second.as(); 82 | else if (a.type() == typeid(unsigned int)) command_line_string << it->second.as(); 83 | else if (a.type() == typeid(float)) command_line_string << it->second.as(); 84 | else command_line_string << "Unknown type" << std::endl; 85 | command_line_string << std::endl; 86 | } 87 | std::cout << command_line_string.str(); 88 | 89 | cudaSetDevice(device); 90 | cudaDeviceReset(); 91 | 92 | string filename = vm["input"].as(); 93 | 94 | auto hoInput = read_nd_array(filename.c_str()); 95 | 96 | 97 | auto input = cuNDArray(*hoInput); 98 | 99 | auto output = input; 100 | nonlocal_meansPoisson(&input,&output,noise); 101 | 102 | write_nd_array(&output,outputFile); 103 | 104 | } 105 | 106 | -------------------------------------------------------------------------------- /denoise/denoise_NLM_prior.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * split_denoise.cpp 3 | 4 | * 5 | * Created on: Dec 10, 2015 6 | * Author: dch 7 | */ 8 | 9 | 10 | #include "hoNDArray_fileio.h" 11 | #include "hoCuNDArray_math.h" 12 | #include "vector_td_utilities.h" 13 | #include "hoNDArray_utils.h" 14 | #include "GPUTimer.h" 15 | #include "cuATrousOperator.h" 16 | #include "cuEdgeATrousOperator.h" 17 | #include "cuSbCgSolver.h" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "subsetAccumulateOperator.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "cuSolverUtils.h" 30 | #include "osPDsolver.h" 31 | #include "osLALMSolver.h" 32 | #include "osLALMSolver2.h" 33 | #include "cuATrousOperator.h" 34 | #include "hdf5_utils.h" 35 | #include "cuEdgeATrousOperator.h" 36 | #include "cuDCTOperator.h" 37 | #include "cuDCTDerivativeOperator.h" 38 | #include "weightingOperator.h" 39 | #include "hoNDArray_math.h" 40 | #include "cuNCGSolver.h" 41 | #include "accumulateOperator.h" 42 | #include "subselectionOperator.h" 43 | #include "subsetConverter.h" 44 | #include "nonlocalMeans.h" 45 | using namespace std; 46 | using namespace Gadgetron; 47 | using namespace std; 48 | 49 | namespace po = boost::program_options; 50 | int main(int argc, char** argv){ 51 | 52 | po::options_description desc("Allowed options"); 53 | unsigned int iterations; 54 | int device; 55 | float noise; 56 | string outputFile; 57 | desc.add_options() 58 | ("help", "produce help message") 59 | ("input,a", po::value(), "Input filename") 60 | ("prior,p", po::value(), "Prior filename") 61 | ("output,f", po::value(&outputFile)->default_value("denoised.real"), "Output filename") 62 | ("device",po::value(&device)->default_value(0),"Number of the device to use (0 indexed)") 63 | ("noise",po::value(&noise)->default_value(1),"noise level") 64 | 65 | 66 | ; 67 | 68 | po::variables_map vm; 69 | po::store(po::parse_command_line(argc, argv, desc), vm); 70 | po::notify(vm); 71 | 72 | if (vm.count("help")) { 73 | cout << desc << "\n"; 74 | return 1; 75 | } 76 | 77 | std::stringstream command_line_string; 78 | std::cout << "Command line options:" << std::endl; 79 | for (po::variables_map::iterator it = vm.begin(); it != vm.end(); ++it){ 80 | boost::any a = it->second.value(); 81 | command_line_string << it->first << ": "; 82 | if (a.type() == typeid(std::string)) command_line_string << it->second.as(); 83 | else if (a.type() == typeid(int)) command_line_string << it->second.as(); 84 | else if (a.type() == typeid(unsigned int)) command_line_string << it->second.as(); 85 | else if (a.type() == typeid(float)) command_line_string << it->second.as(); 86 | else command_line_string << "Unknown type" << std::endl; 87 | command_line_string << std::endl; 88 | } 89 | std::cout << command_line_string.str(); 90 | 91 | cudaSetDevice(device); 92 | cudaDeviceReset(); 93 | 94 | string filename = vm["input"].as(); 95 | 96 | auto hoInput = read_nd_array(filename.c_str()); 97 | 98 | 99 | auto input = cuNDArray(*hoInput); 100 | 101 | auto prior = cuNDArray(*read_nd_array(vm["prior"].as().c_str())); 102 | 103 | float* input_ptr = input.get_data_ptr(); 104 | for (int i = 0; i < input.get_size(3); i++) { 105 | cuNDArray out_view(prior.get_dimensions(),input_ptr); 106 | auto in_view = out_view; 107 | nonlocal_means_ref(&in_view,&out_view, &prior, noise); 108 | input_ptr += in_view.get_number_of_elements(); 109 | } 110 | 111 | 112 | write_nd_array(&input,outputFile); 113 | 114 | } 115 | 116 | -------------------------------------------------------------------------------- /denoise/nonlocalMeans.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace Gadgetron{ 4 | void nonlocal_means( cuNDArray *input, cuNDArray *output , float Noise); 5 | void nonlocal_meansPoisson( cuNDArray *input, cuNDArray *output , float Noise); 6 | void nonlocal_means_block( cuNDArray *input, cuNDArray *output , float Noise); 7 | void nonlocal_means_ref( cuNDArray *input,cuNDArray* output, cuNDArray *ref , float Noise); 8 | void nonlocal_means2D( cuNDArray *input, cuNDArray *output , float Noise); 9 | void nonlocal_means2DPoisson( cuNDArray *input, cuNDArray *output , float Noise); 10 | void nonlocal_means_block2DPoisson( cuNDArray *input, cuNDArray *output , float Noise); 11 | 12 | }; -------------------------------------------------------------------------------- /mri/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_SOURCE_DIR}/operators) 2 | include_directories(${CMAKE_SOURCE_DIR}/solvers) 3 | 4 | #add_executable(radial_sense_sbc main_sbc.cpp) 5 | add_executable(radial_sense_ncg main_ncg.cpp) 6 | #add_executable(radial_sense_fista main_fista.cpp) 7 | 8 | MESSAGE("CUDA LIBRARIES: ${CUDA_LIBRARIES}") 9 | 10 | #target_link_libraries(radial_sense_sbc tomography_operators gpuoperators cpucore gpucore gpuparallelmri gpunfft hostutils gpusolvers ${CUDA_LIBRARIES}) 11 | 12 | target_link_libraries(radial_sense_ncg tomography_operators tomography_solvers gpuoperators cpucore gpucore gpuparallelmri gpunfft hostutils gpusolvers ${CUDA_LIBRARIES} ${CULA_LIBRARIES}) 13 | #target_link_libraries(radial_sense_fista tomography_operators gpuoperators cpucore gpucore gpuparallelmri gpunfft hostutils gpusolvers ${CUDA_LIBRARIES}) 14 | 15 | -------------------------------------------------------------------------------- /operators/BilateralPriorOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray.h" 3 | #include "cuBilateralFilter.h" 4 | 5 | namespace Gadgetron { 6 | 7 | class BilateralPriorOperator : public linearOperator> { 8 | public: 9 | BilateralPriorOperator() : sigma_int(1),sigma_spatial(1) {} 10 | 11 | void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate = false) override{ 12 | auto out_tmp = out; 13 | if (accumulate) out_tmp = new cuNDArray(in->get_dimensions()); 14 | *out_tmp = *in; 15 | 16 | 17 | std::vector dims3D{in->get_size(0),in->get_size(1),in->get_size(2)}; 18 | 19 | auto out_ptr = out_tmp->get_data_ptr(); 20 | auto in_ptr = in->get_data_ptr(); 21 | 22 | for (int i = 0; i < in->get_size(3); i++) { 23 | 24 | cuNDArray out3D(dims3D,out_ptr); 25 | bilateral_filter(&out3D, prior.get(), sigma_spatial, sigma_int); 26 | out_ptr += out3D.get_number_of_elements(); 27 | } 28 | *out_tmp -= *in; 29 | 30 | if (accumulate) { 31 | *out += *out_tmp; 32 | delete out_tmp; 33 | } 34 | } 35 | 36 | void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate = false) override { 37 | 38 | if (!norm_image) update_norm(); 39 | 40 | auto out_tmp = out; 41 | if (accumulate) out_tmp = new cuNDArray(in->get_dimensions()); 42 | *out_tmp = *in; 43 | 44 | 45 | std::vector dims3D{in->get_size(0),in->get_size(1),in->get_size(2)}; 46 | 47 | auto out_ptr = out_tmp->get_data_ptr(); 48 | auto in_ptr = in->get_data_ptr(); 49 | 50 | for (int i = 0; i < in->get_size(3); i++) { 51 | 52 | cuNDArray out3D(dims3D,out_ptr); 53 | out3D /= *norm_image; 54 | bilateral_filter_unnormalized(&out3D, prior.get(), sigma_spatial, sigma_int); 55 | out_ptr += out3D.get_number_of_elements(); 56 | } 57 | *out_tmp -= *in; 58 | 59 | if (accumulate) { 60 | *out += *out_tmp; 61 | delete out_tmp; 62 | } 63 | } 64 | 65 | void set_prior(boost::shared_ptr> p){ 66 | prior = p; 67 | norm_image = boost::shared_ptr>(); 68 | } 69 | 70 | void set_sigma_int(float sigma) { 71 | sigma_int = sigma; 72 | norm_image = boost::shared_ptr>(); 73 | } 74 | void set_sigma_spatial(float sigma) { 75 | sigma_spatial = sigma; 76 | norm_image = boost::shared_ptr>(); 77 | } 78 | protected: 79 | 80 | void update_norm(){ 81 | norm_image = boost::make_shared>(prior->get_dimensions()); 82 | fill(norm_image.get(),1.0f); 83 | bilateral_filter_unnormalized(norm_image.get(),prior.get(),sigma_spatial,sigma_int); 84 | } 85 | 86 | float sigma_int,sigma_spatial; 87 | boost::shared_ptr> prior; 88 | boost::shared_ptr> norm_image; 89 | 90 | 91 | }; 92 | 93 | }; -------------------------------------------------------------------------------- /operators/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (WIN32) 2 | ADD_DEFINITIONS(-D__BUILD_GADGETRON_SOLVERS__) 3 | endif (WIN32) 4 | 5 | 6 | cuda_add_library( tomography_operators SHARED 7 | cuHaarWaveletOperator.cu 8 | cuGaussianFilterOperator.cu 9 | cuATrousWavelet.cu 10 | cuEdgeWavelet.cu 11 | cuDCT.cu 12 | cuPartialDifferenceOperator.cu 13 | cuSmallConvOperator.cu 14 | cuScaleOperator.cu 15 | cuTVPrimalDualOperator.cu 16 | cuWTVPrimalDualOperator.cu 17 | cuBilateralFilter.cu 18 | cuTFFT.cpp 19 | cuBoxFilterOperator.cu 20 | ) 21 | target_link_libraries(tomography_operators gadgetron_toolbox_gpusolvers gadgetron_toolbox_gpucore gadgetron_toolbox_gpuoperators gadgetron_toolbox_gpunfft gadgetron_toolbox_gpucore gadgetron_toolbox_gpufft gadgetron_toolbox_gpureg ${CUDA_LIBRARIES} ${DCMTK_dcmdata_LIBRARY} ${DCMTK_oflog_LIBRARY} ${DCMTK_ofstd_LIBRARY} ${GDCM_LIBRARIES}) 22 | install(FILES 23 | cuPartialDifferenceOperator.h 24 | hoCuPartialDerivativeOperator.h 25 | cuGaussianFilterOperator.h 26 | # subsetOperator.h 27 | cuATrousWavelet.h 28 | invertibleOperator.h 29 | cuDCT.h 30 | DESTINATION include) 31 | -------------------------------------------------------------------------------- /operators/accumulateOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "linearOperator.h" 4 | 5 | namespace Gadgetron { 6 | 7 | template class accumulateOperator : public linearOperator{ 8 | public: 9 | accumulateOperator(boost::shared_ptr > op_) : linearOperator(), op(op_){} 10 | 11 | virtual void mult_M(ARRAY* in, ARRAY* out, bool accumulate = false ){ 12 | auto dims = *in->get_dimensions(); 13 | auto back_dim = dims.back(); 14 | dims.pop_back(); 15 | ARRAY tmp(dims); 16 | clear(&tmp); 17 | auto elements = tmp.get_number_of_elements(); 18 | 19 | for (auto i =0u; i < back_dim; i++){ 20 | ARRAY view(dims,in->get_data_ptr()+elements*i); 21 | tmp += view; 22 | } 23 | 24 | op->mult_M(&tmp,out,accumulate); 25 | 26 | } 27 | 28 | virtual void mult_MH(ARRAY* in, ARRAY* out, bool accumulate = false ){ 29 | auto dims = *out->get_dimensions(); 30 | auto back_dim = dims.back(); 31 | dims.pop_back(); 32 | ARRAY tmp(dims); 33 | auto elements = tmp.get_number_of_elements(); 34 | op->mult_MH(in,&tmp); 35 | for (auto i =0u; i < back_dim; i++){ 36 | ARRAY view(dims,out->get_data_ptr()+elements*i); 37 | if (accumulate) 38 | view += tmp; 39 | else 40 | view = tmp; 41 | } 42 | 43 | } 44 | protected: 45 | boost::shared_ptr> op; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /operators/cuATVPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTVPrimalDualOperator.h" 5 | #include 6 | #include "cuBoxFilterOperator.h" 7 | namespace Gadgetron { 8 | template 9 | class cuATVPrimalDualOperator : public cuTVPrimalDualOperator { 10 | typedef cuTVPrimalDualOperator parent; 11 | 12 | cuScaleOperator scaleOp; 13 | //cuBoxFilterOperator scaleOp; 14 | public: 15 | cuATVPrimalDualOperator() : parent() {} 16 | cuATVPrimalDualOperator(T alpha_ ) : parent(alpha_){} 17 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override { 18 | auto dims_small = *in->get_dimensions(); 19 | for (int i = 0; i < 3; i++) 20 | dims_small[i] /= 2; 21 | 22 | cuNDArray tmp_in(dims_small); 23 | cuNDArray tmp_out(dims_small); 24 | 25 | scaleOp.mult_M(in,&tmp_in); 26 | parent::primalDual(&tmp_in,&tmp_out,sigma,false); 27 | scaleOp.mult_MH(&tmp_out,out,accumulate); 28 | 29 | 30 | 31 | }; 32 | 33 | 34 | 35 | 36 | }; 37 | } -------------------------------------------------------------------------------- /operators/cuATrousWavelet.cu: -------------------------------------------------------------------------------- 1 | #include "cuATrousWavelet.h" 2 | #include "complext.h" 3 | //#include "setup_grid.h" 4 | #include "cuNDArray_math.h" 5 | #include "cudaDeviceManager.h" 6 | using namespace Gadgetron; 7 | 8 | static inline 9 | void setup_grid( unsigned int number_of_elements, dim3 *blockDim, dim3* gridDim, unsigned int num_batches = 1 ) 10 | { 11 | int cur_device = cudaDeviceManager::Instance()->getCurrentDevice(); 12 | //int maxGridDim = cudaDeviceManager::Instance()->max_griddim(cur_device); 13 | int maxBlockDim = cudaDeviceManager::Instance()->max_blockdim(cur_device); 14 | int maxGridDim = 65535; 15 | 16 | // The default one-dimensional block dimension is... 17 | *blockDim = dim3(256); 18 | *gridDim = dim3((number_of_elements+blockDim->x-1)/blockDim->x, num_batches); 19 | 20 | // Extend block/grid dimensions if we exceeded the maximum grid dimension 21 | if( gridDim->x > maxGridDim){ 22 | blockDim->x = maxBlockDim; 23 | gridDim->x = (number_of_elements+blockDim->x-1)/blockDim->x; 24 | } 25 | 26 | if( gridDim->x > maxGridDim ){ 27 | gridDim->x = (unsigned int)std::floor(std::sqrt(float(number_of_elements)/float(blockDim->x))); 28 | unsigned int num_elements_1d = blockDim->x*gridDim->x; 29 | gridDim->y *= ((number_of_elements+num_elements_1d-1)/num_elements_1d); 30 | } 31 | 32 | if( gridDim->x > maxGridDim || gridDim->y > maxGridDim){ 33 | // If this ever becomes an issue, there is an additional grid dimension to explore for compute models >= 2.0. 34 | throw cuda_error("setup_grid(): too many elements requested."); 35 | } 36 | } 37 | static __device__ void atomicAdd(float_complext * ptr, float_complext val){ 38 | 39 | atomicAdd((float*) ptr, real(val)); 40 | atomicAdd(((float*)ptr)+1,imag(val)); 41 | } 42 | template __global__ void aTrous_kernel(const T* __restrict__ image, T* __restrict__ out, int stepsize, int stride, int dim_length, typename realType::Type * kernel, int kernel_length, int tot_elements){ 43 | 44 | const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; 45 | 46 | if (idx < tot_elements){ 47 | T result = 0; 48 | 49 | const int dim_pos = (idx/stride)%dim_length; 50 | const int offset = idx-dim_pos*stride; 51 | for (int i = -kernel_length/2; i <= kernel_length/2; i++){ 52 | int pos = (dim_pos+i*stepsize+dim_length)%dim_length; 53 | result += image[pos*stride+offset]*kernel[i+kernel_length/2]; 54 | } 55 | atomicAdd(out+idx,result); 56 | } 57 | } 58 | 59 | 60 | 61 | template void Gadgetron::aTrousWavelet(cuNDArray* in, cuNDArray* out, thrust::device_vector::Type>* kernel, int stepsize,int dim, bool accumulate){ 62 | 63 | dim3 dimGrid,dimBlock; 64 | setup_grid(in->get_number_of_elements(),&dimBlock,&dimGrid,1); 65 | 66 | if (dim >= in->get_number_of_dimensions()) 67 | throw std::runtime_error("aTrousWavelet: input array has insufficient number of dimensions"); 68 | 69 | int max_grid = cudaDeviceManager::Instance()->max_griddim(); 70 | 71 | 72 | int stride = 1; 73 | for (int i = 0; i < dim; i++) stride *= in->get_size(i); 74 | 75 | if (!accumulate) 76 | clear(out); 77 | aTrous_kernel<<>>(in->get_data_ptr(), out->get_data_ptr(),stepsize,stride,in->get_size(dim),thrust::raw_pointer_cast(kernel->data()),kernel->size(),in->get_number_of_elements()); 78 | 79 | } 80 | 81 | 82 | template void Gadgetron::aTrousWavelet(cuNDArray*, cuNDArray*, thrust::device_vector*, int, int, bool); 83 | template void Gadgetron::aTrousWavelet(cuNDArray*, cuNDArray*, thrust::device_vector*, int, int, bool); 84 | -------------------------------------------------------------------------------- /operators/cuATrousWavelet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "cuNDArray.h" 5 | namespace Gadgetron { 6 | 7 | 8 | template void aTrousWavelet(cuNDArray* in, cuNDArray* out, thrust::device_vector::Type>* kernel, int stepsize,int dim, bool accumulate); 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /operators/cuATvOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gpuoperators_export.h" 4 | #include "cuNDArray_math.h" 5 | #include "generalOperator.h" 6 | 7 | #include "complext.h" 8 | #include "cuScaleOperator.h" 9 | 10 | namespace Gadgetron{ 11 | 12 | template class cuATvOperator 13 | : public cuTvOperator 14 | { 15 | 16 | 17 | public: 18 | typedef typename realType::Type REAL; 19 | 20 | cuATvOperator() : cuTvOperator(){ 21 | 22 | } 23 | 24 | virtual ~cuATvOperator(){}; 25 | 26 | virtual void gradient(cuNDArray* in ,cuNDArray* out, bool accumulate=false){ 27 | auto dims_small = *in->get_dimensions(); 28 | for (int i = 0; i < 3; i++) 29 | dims_small[i] /= 2; 30 | 31 | cuNDArray tmp_in(dims_small); 32 | cuNDArray tmp_out(dims_small); 33 | 34 | scaleOp.mult_M(in,&tmp_in); 35 | parent::gradient(&tmp_in,&tmp_out,false); 36 | scaleOp.mult_MH(&tmp_out,out,accumulate); 37 | 38 | 39 | }; 40 | virtual REAL magnitude(cuNDArray* in){ 41 | auto dims_small = *in->get_dimensions(); 42 | for (int i = 0; i < 3; i++) 43 | dims_small[i] /= 2; 44 | 45 | cuNDArray tmp_in(dims_small); 46 | return parent::magnitude(&tmp_in); 47 | } 48 | 49 | protected: 50 | typedef cuTvOperator parent; 51 | protected: 52 | REAL limit_; 53 | cuScaleOperator scaleOp; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /operators/cuBilateralFilter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray.h" 3 | 4 | namespace Gadgetron { 5 | void bilateral_filter(cuNDArray* image, cuNDArray* ref_image,float sigma_spatial,float sigma_int); 6 | void bilateral_filter_unnormalized(cuNDArray* image, cuNDArray* ref_image,float sigma_spatial,float sigma_int); 7 | } 8 | -------------------------------------------------------------------------------- /operators/cuBilateralPriorPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTVPrimalDualOperator.h" 5 | #include "cuWTVPrimalDualOperator.h" 6 | #include 7 | #include "BilateralPriorOperator.h" 8 | 9 | namespace Gadgetron { 10 | 11 | class cuBilateralPriorPrimalDualOperator : public cuTVPrimalDualOperator { 12 | typedef cuTVPrimalDualOperator parent; 13 | 14 | 15 | BilateralPriorOperator bilOp; 16 | public: 17 | cuBilateralPriorPrimalDualOperator() : parent() { 18 | } 19 | cuBilateralPriorPrimalDualOperator(float sigma_int, float sigma_spatial, boost::shared_ptr> prior, float alpha_= 0 ) : parent(alpha_){ 20 | bilOp = BilateralPriorOperator(); 21 | bilOp.set_sigma_spatial(sigma_spatial); 22 | bilOp.set_sigma_int(sigma_int); 23 | bilOp.set_prior(prior); 24 | } 25 | virtual void primalDual(cuNDArray* in, cuNDArray* out,float sigma, bool accumulate) override { 26 | 27 | 28 | cuNDArray tmp_in = *in; 29 | cuNDArray tmp_out = *out; 30 | bilOp.mult_M(in,&tmp_in); 31 | parent::primalDual(&tmp_in,&tmp_out,sigma,false); 32 | bilOp.mult_MH(&tmp_out,out,accumulate); 33 | 34 | 35 | 36 | }; 37 | 38 | 39 | 40 | 41 | 42 | 43 | }; 44 | } -------------------------------------------------------------------------------- /operators/cuBoxFilterOperator.cu: -------------------------------------------------------------------------------- 1 | #include "cuBoxFilterOperator.h" 2 | 3 | #include "gpuoperators_export.h" 4 | #include "vector_td_utilities.h" 5 | 6 | using namespace Gadgetron; 7 | 8 | 9 | 10 | 11 | template static __global__ void 12 | box_kernel_simpel(T* __restrict__ in, T* __restrict__ out, vector_td dims,int direction){ 13 | 14 | const int ixo = blockDim.x * blockIdx.x + threadIdx.x; 15 | const int iyo = blockDim.y * blockIdx.y + threadIdx.y; 16 | const int izo = blockDim.z * blockIdx.z + threadIdx.z; 17 | 18 | 19 | vector_td coord(ixo,iyo,izo); 20 | vector_td coord2(ixo,iyo,izo); 21 | if (ixo < dims[0] && iyo < dims[1] && izo < dims[2]){ 22 | 23 | 24 | T res = T(0); 25 | 26 | 27 | for (int i = 0; i < 2; i++){ 28 | coord2[D] = coord[D]+ direction*i; 29 | res += in[co_to_idx<3>((coord2+dims)%dims,dims)]; 30 | 31 | } 32 | 33 | //atomicAdd(&out[co_to_idx<3>(coord,dims)],res/norm); 34 | out[co_to_idx<3>(coord,dims)] = res*0.5f; 35 | } 36 | 37 | } 38 | template static void boxFilter(cuNDArray* in,cuNDArray* out, bool accumulate,int direction){ 39 | 40 | 41 | vector_td dims = from_std_vector(*(in->get_dimensions())); 42 | 43 | *out = *in; 44 | std::vector batch_dim = to_std_vector(dims); 45 | size_t elements = prod(dims); 46 | for (int batch =0; batch < in->get_number_of_elements()/elements; batch++){ 47 | 48 | 49 | T* outptr = out->get_data_ptr()+batch*elements; 50 | cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(); 51 | cudaExtent extent; 52 | extent.width = in->get_size(0); 53 | extent.height = in->get_size(1); 54 | extent.depth = in->get_size(2); 55 | 56 | dim3 threads(8,8,8); 57 | 58 | dim3 grid((extent.width+threads.x-1)/threads.x, (extent.height+threads.y-1)/threads.y,(extent.depth+threads.z-1)/threads.z); 59 | 60 | for (int d = 0; d < D; d++){ 61 | if (dims[d] ==1) continue; 62 | 63 | cuNDArray tmp(elements); 64 | cudaMemcpy(tmp.get_data_ptr(),outptr,elements*sizeof(T),cudaMemcpyDeviceToDevice); 65 | if (d == 0) 66 | box_kernel_simpel<<>>(tmp.get_data_ptr(),outptr,vector_td(extent.width,extent.height,extent.depth),direction); 67 | else if (d == 1) 68 | box_kernel_simpel<<>>(tmp.get_data_ptr(),outptr,vector_td(extent.width,extent.height,extent.depth),direction); 69 | else if (d == 2) 70 | box_kernel_simpel<<>>(tmp.get_data_ptr(),outptr,vector_td(extent.width,extent.height,extent.depth),direction); 71 | else throw std::runtime_error("Unsupported number of dimensions for Gaussian kernel"); 72 | 73 | 74 | 75 | } 76 | 77 | 78 | 79 | 80 | //cudaFreeArray(image_array); 81 | if (accumulate) *out += *in; 82 | 83 | 84 | } 85 | 86 | 87 | 88 | } 89 | 90 | 91 | template void cuBoxFilterOperator::mult_M(cuNDArray* in,cuNDArray* out, bool accumulate){ 92 | boxFilter(in,out,accumulate,1); 93 | } 94 | 95 | 96 | template void cuBoxFilterOperator::mult_MH(cuNDArray* in,cuNDArray* out, bool accumulate){ 97 | boxFilter(in,out,accumulate,-1); 98 | } 99 | 100 | 101 | template EXPORTGPUOPERATORS class cuBoxFilterOperator; 102 | template EXPORTGPUOPERATORS class cuBoxFilterOperator; 103 | template EXPORTGPUOPERATORS class cuBoxFilterOperator; 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /operators/cuBoxFilterOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperator.h" 3 | #include "cuNDArray.h" 4 | #include "cuNDArray_math.h" 5 | namespace Gadgetron{ 6 | 7 | 8 | template class cuBoxFilterOperator : public linearOperator > { 9 | typedef typename realType::Type REAL; 10 | public: 11 | void mult_M( cuNDArray* in, cuNDArray* out, bool accumulate = false); 12 | void mult_MH( cuNDArray* in, cuNDArray* out, bool accumulate = false); 13 | 14 | 15 | 16 | }; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /operators/cuDCT.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray.h" 3 | 4 | namespace Gadgetron { 5 | template void dct2(cuNDArray* image,int offset=0); 6 | template void idct2(cuNDArray* image, int offset=0); 7 | template void dct(cuNDArray* image,int dim, int offset=0); 8 | template void idct(cuNDArray* image, int dim, int offset=0); 9 | } 10 | -------------------------------------------------------------------------------- /operators/cuDCTDerivativeOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperator.h" 3 | #include "cuPartialDerivativeOperator.h" 4 | 5 | namespace Gadgetron { 6 | 7 | template class cuDCTDerivativeOperator : public linearOperator> { 8 | 9 | 10 | public: 11 | 12 | cuDCTDerivativeOperator(size_t dim) : linearOperator>() { 13 | pD = cuPartialDerivativeOperator(dim); 14 | } 15 | 16 | 17 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate) override { 18 | 19 | auto tmp = out; 20 | if (accumulate) tmp = new cuNDArray(out->get_dimensions()); 21 | pD.mult_M(in,tmp,false); 22 | dct(tmp,3); 23 | if (accumulate){ 24 | *out += *tmp; 25 | delete tmp; 26 | } 27 | } 28 | 29 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate) override { 30 | 31 | auto tmp = *in; 32 | idct(&tmp,3); 33 | pD.mult_MH(&tmp,out,accumulate); 34 | 35 | } 36 | 37 | 38 | protected: 39 | cuPartialDerivativeOperator pD; 40 | }; 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /operators/cuDCTOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuDCT.h" 3 | 4 | #include "invertibleOperator.h" 5 | 6 | namespace Gadgetron { 7 | 8 | template class cuDCTOperator : public Gadgetron::invertibleOperator> { 9 | 10 | static constexpr int stencil_size = 8; 11 | public: 12 | 13 | cuDCTOperator(): invertibleOperator>(){ 14 | repetitions = 2; 15 | }; 16 | 17 | virtual ~cuDCTOperator(){}; 18 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate=false) override { 19 | 20 | cuNDArray* tmp = out; 21 | 22 | if (accumulate) tmp = new cuNDArray(out->get_dimensions()); 23 | 24 | auto in_dims = in->get_dimensions(); 25 | size_t elements = in->get_number_of_elements(); 26 | for (auto i = 0; i < repetitions; i++){ 27 | cuNDArray tmp_view(in_dims,tmp->get_data_ptr()+elements*i); 28 | tmp_view = *in; 29 | dct2(&tmp_view,i*stencil_size/repetitions); 30 | if (in->get_size(2) > 1) 31 | dct(&tmp_view,2,i*stencil_size/repetitions); 32 | if (in->get_size(3) > 1) 33 | dct(&tmp_view,3,i*10/repetitions); 34 | //dct2(&tmp_view,2); 35 | } 36 | 37 | *tmp /= std::sqrt(T(repetitions)); 38 | if (accumulate){ 39 | *out += *tmp; 40 | delete tmp; 41 | } 42 | 43 | } 44 | 45 | 46 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate=false) override { 47 | 48 | 49 | if (!accumulate) clear(out); 50 | 51 | auto out_dims = out->get_dimensions(); 52 | size_t elements = out->get_number_of_elements(); 53 | for (auto i = 0; i < repetitions; i++){ 54 | cuNDArray in_view(out_dims,in->get_data_ptr()+i*elements); 55 | cuNDArray tmp(in_view); 56 | idct2(&tmp,i*stencil_size/repetitions); 57 | if (out->get_size(2) > 1) 58 | idct(&tmp,2,i*stencil_size/repetitions); 59 | if (out->get_size(3) > 1) 60 | idct(&tmp,3,i*10/repetitions); 61 | //idct2(&tmp,2); 62 | axpy(std::sqrt(T(1)/repetitions),&tmp,out); 63 | } 64 | 65 | } 66 | 67 | virtual void inverse(cuNDArray* in, cuNDArray* out, bool accumulate=false) override { 68 | mult_MH(in,out,accumulate); 69 | } 70 | 71 | 72 | 73 | virtual void set_domain_dimensions(std::vector* dims) override { 74 | std::vector codims = *dims; 75 | codims.push_back(repetitions); 76 | linearOperator>::set_codomain_dimensions(&codims); 77 | linearOperator>::set_domain_dimensions(dims); 78 | } 79 | 80 | virtual void set_codomain_dimensions(std::vector* dims) override { 81 | throw std::runtime_error("Do not set codomain dimensions manually"); 82 | } 83 | 84 | protected: 85 | unsigned int repetitions; 86 | 87 | 88 | }; 89 | }; 90 | -------------------------------------------------------------------------------- /operators/cuEdgeWavelet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "cuNDArray.h" 5 | namespace Gadgetron { 6 | 7 | 8 | template void EdgeWavelet(cuNDArray* in, cuNDArray* out, thrust::device_vector::Type>* kernel, int stepsize,int dim,typename realType::Type sigma, bool accumulate); 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /operators/cuFFTDerivativeOperator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "linearOperator.h" 4 | #include "cuPartialDerivativeOperator.h" 5 | #include "cuRFFTOperator.h" 6 | 7 | namespace Gadgetron { 8 | 9 | template class cuDCTDerivativeOperator : public linearOperator> { 10 | 11 | 12 | public: 13 | 14 | cuDCTDerivativeOperator(size_t dim) : linearOperator>(), fftOp(cuRFFTOperator(3)) { 15 | } 16 | 17 | 18 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate) override { 19 | 20 | cuNDArray tmp(in->get_dimensions()); 21 | pD.mult_M(in,&tmp,false); 22 | 23 | fftOp.mult_M(&tmp,out,accumulate); 24 | /*dct(tmp,3); 25 | if (accumulate){ 26 | *out += *tmp; 27 | delete tmp; 28 | }*/ 29 | } 30 | 31 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate) override { 32 | 33 | auto tmp = *out; 34 | //idct(&tmp,3); 35 | fftOp.mult_MH(in,&tmp,false); 36 | pD.mult_MH(&tmp,out,accumulate); 37 | 38 | } 39 | 40 | 41 | virtual void set_domain_dimensions(std::vector* dims) override { 42 | fftOp.set_domain_dimensions(dims); 43 | } 44 | 45 | boost::shared_ptr > get_codomain_dimensions() override { 46 | return fftOp.get_codomain_dimensions(); 47 | } 48 | 49 | protected: 50 | cuRFFTOperator fftOp; 51 | }; 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /operators/cuFrameletOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "linearOperator.h" 4 | #include "cuNDArray_operators.h" 5 | #include "cuNDArray.h" 6 | 7 | namespace Gadgetron { 8 | 9 | template class cuFrameletOperator : public linearOperator >{ 10 | 11 | public: 12 | cuFrameletOperator() : linearOperator >(){}; 13 | 14 | virtual ~cuFrameletOperator(){}; 15 | virtual void mult_M(cuNDArray*,cuNDArray*,bool ); 16 | virtual void mult_MH(cuNDArray*,cuNDArray*,bool ); 17 | virtual void mult_MH_M(cuNDArray* in ,cuNDArray* out,bool accumulate ){ 18 | if (accumulate){ 19 | *out += *in; 20 | } else { 21 | *out = *in; 22 | } 23 | } 24 | virtual boost::shared_ptr< linearOperator< cuNDArray > > clone(){ 25 | return linearOperator< cuNDArray >::clone(this); 26 | } 27 | virtual void set_domain_dimensions(std::vector* dims); 28 | 29 | }; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /operators/cuGaussianFilterOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperator.h" 3 | #include "cuNDArray.h" 4 | #include "cuNDArray_math.h" 5 | namespace Gadgetron{ 6 | 7 | 8 | template class cuGaussianFilterOperator : public linearOperator > { 9 | typedef typename realType::Type REAL; 10 | public: 11 | void mult_M( cuNDArray* in, cuNDArray* out, bool accumulate = false); 12 | void mult_MH( cuNDArray* in, cuNDArray* out, bool accumulate = false); 13 | void set_sigma(REAL sigma){ _sigma= vector_td(sigma);} 14 | void set_sigma(vector_td sigma){ _sigma= sigma;} 15 | protected: 16 | 17 | vector_td _sigma; 18 | 19 | 20 | }; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /operators/cuHaarWaveletOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "linearOperator.h" 4 | #include "cuNDArray_operators.h" 5 | #include "cuNDArray.h" 6 | 7 | namespace Gadgetron { 8 | 9 | template class cuHaarWaveletOperator : public linearOperator >{ 10 | 11 | public: 12 | cuHaarWaveletOperator() : linearOperator >(){}; 13 | 14 | virtual ~cuHaarWaveletOperator(){}; 15 | virtual void mult_M(cuNDArray*,cuNDArray*,bool ); 16 | virtual void mult_MH(cuNDArray*,cuNDArray*,bool ); 17 | virtual void mult_MH_M(cuNDArray* in ,cuNDArray* out,bool accumulate ){ 18 | if (accumulate){ 19 | *out += *in; 20 | } else { 21 | *out = *in; 22 | } 23 | } 24 | virtual void set_domain_dimensions(std::vector* dims); 25 | 26 | }; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /operators/cuPICSDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTVPrimalDualOperator.h" 5 | #include 6 | namespace Gadgetron { 7 | template 8 | class cuPICSPrimalDualOperator : public cuTVPrimalDualOperator { 9 | typedef cuTVPrimalDualOperator parent; 10 | 11 | public: 12 | cuPICSPrimalDualOperator() : parent() {} 13 | cuPICSPrimalDualOperator(T alpha_ ) : parent(alpha_){} 14 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override { 15 | 16 | auto tmp_in = *in; 17 | tmp_in -= *prior; 18 | parent::primalDual(&tmp_in,out,sigma,accumulate); 19 | 20 | }; 21 | 22 | void set_prior(boost::shared_ptr> p){ 23 | prior = p; 24 | } 25 | 26 | protected: 27 | boost::shared_ptr> prior; 28 | 29 | 30 | }; 31 | } -------------------------------------------------------------------------------- /operators/cuPartialDifferenceOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuNDArray_math.h" 4 | #include "linearOperator.h" 5 | 6 | 7 | 8 | namespace Gadgetron { 9 | template 10 | class cuPartialDifferenceOperator : public linearOperator> { 11 | 12 | public: 13 | cuPartialDifferenceOperator(int diff_dim) : linearOperator>(), dim(diff_dim) { 14 | 15 | } 16 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate) override; 17 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate) override; 18 | 19 | int dim; 20 | }; 21 | } -------------------------------------------------------------------------------- /operators/cuSSTVPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTVPrimalDualOperator.h" 5 | #include 6 | #include "cuGaussianFilterOperator.h" 7 | namespace Gadgetron { 8 | template 9 | class cuSSTVPrimalDualOperator : public cuTVPrimalDualOperator { 10 | typedef cuTVPrimalDualOperator parent; 11 | 12 | cuScaleOperator scaleOp; 13 | cuGaussianFilterOperator gauss; 14 | public: 15 | cuSSTVPrimalDualOperator() : parent() { 16 | gauss = cuGaussianFilterOperator(); 17 | gauss.set_sigma(1); 18 | } 19 | cuSSTVPrimalDualOperator(T alpha_ ) : parent(alpha_){ 20 | gauss = cuGaussianFilterOperator(); 21 | gauss.set_sigma(1); 22 | } 23 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override { 24 | auto dims_small = *in->get_dimensions(); 25 | for (int i = 0; i < 3; i++) 26 | dims_small[i] /= 2; 27 | 28 | cuNDArray tmp_in(in->get_dimensions()); 29 | cuNDArray tmp_out(in->get_dimensions()); 30 | gauss.mult_M(in,&tmp_in); 31 | 32 | cuNDArray tmp_in_small(dims_small); 33 | cuNDArray tmp_out_small(dims_small); 34 | 35 | scaleOp.mult_M(&tmp_in,&tmp_in_small); 36 | parent::primalDual(&tmp_in_small,&tmp_out_small,sigma,false); 37 | 38 | scaleOp.mult_MH(&tmp_out_small,&tmp_out); 39 | gauss.mult_MH(&tmp_out,out,accumulate); 40 | 41 | 42 | 43 | }; 44 | 45 | 46 | 47 | 48 | 49 | 50 | }; 51 | } -------------------------------------------------------------------------------- /operators/cuScaleOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuNDArray_math.h" 4 | #include "linearOperator.h" 5 | 6 | 7 | 8 | namespace Gadgetron { 9 | template 10 | class cuScaleOperator : public linearOperator> { 11 | 12 | public: 13 | cuScaleOperator() : linearOperator>() { 14 | 15 | } 16 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate=false) override; 17 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate=false) override; 18 | 19 | }; 20 | } -------------------------------------------------------------------------------- /operators/cuSmallConvOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuNDArray_math.h" 4 | #include "linearOperator.h" 5 | 6 | 7 | 8 | namespace Gadgetron { 9 | template 10 | class cuSmallConvOperator : public linearOperator> { 11 | 12 | public: 13 | cuSmallConvOperator(vector_td input_stencil, int conv_dim, int step_size = 1) : linearOperator>(), stencil(input_stencil),dim(conv_dim),stride(step_size) { 14 | for (int i = 0; i < STENCIL_SIZE; i++) 15 | reverse_stencil[i] = stencil[STENCIL_SIZE-i-1]; 16 | 17 | } 18 | virtual void mult_M(cuNDArray* in, cuNDArray* out, bool accumulate) override; 19 | virtual void mult_MH(cuNDArray* in, cuNDArray* out, bool accumulate) override; 20 | 21 | private: 22 | vector_td stencil; 23 | vector_td reverse_stencil; 24 | int dim; 25 | int stride; 26 | }; 27 | } -------------------------------------------------------------------------------- /operators/cuTFFT.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 19/12/16. 3 | // 4 | 5 | #include "cuTFFT.h" 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace Gadgetron; 11 | 12 | void cuTFFT::mult_M(cuNDArray * in, cuNDArray * out, bool accumulate) { 13 | 14 | cufftHandle plan; 15 | 16 | cuNDArray * out_tmp = out; 17 | if (accumulate) 18 | out_tmp = new cuNDArray(out->get_dimensions()); 19 | 20 | std::vector tdim{in->get_size(3)}; 21 | int istride = in->get_size(0)*in->get_size(1)*in->get_size(2); 22 | 23 | auto cuRes = cufftPlanMany(&plan, 1,tdim.data(),tdim.data(),istride,1,tdim.data(),istride,1,CUFFT_R2C,istride); 24 | if (cuRes != CUFFT_SUCCESS) { 25 | std::stringstream ss; 26 | ss << "cuNDFFT FFT plan failed: " << cuRes; 27 | throw std::runtime_error(ss.str()); 28 | } 29 | 30 | auto result = cufftExecR2C(plan,(cufftReal*) in->get_data_ptr(), (cufftComplex*) out_tmp->get_data_ptr()); 31 | if (result != CUFFT_SUCCESS) { 32 | std::stringstream ss; 33 | ss << "cuNDFFT FFT plan failed: " << result; 34 | throw std::runtime_error(ss.str()); 35 | } 36 | 37 | *out_tmp *= 1.0f/std::sqrt(float(in->get_size(3))); 38 | if (accumulate){ 39 | *out += *out_tmp; 40 | delete out_tmp; 41 | } 42 | cufftDestroy(plan); 43 | 44 | 45 | } 46 | 47 | 48 | void cuTFFT::mult_MH(cuNDArray * in, cuNDArray * out, bool accumulate) { 49 | 50 | cuNDArray * out_tmp = out; 51 | if (accumulate) 52 | out_tmp = new cuNDArray(out->get_dimensions()); 53 | 54 | cufftHandle plan; 55 | 56 | std::vector tdim{out->get_size(3)}; 57 | int istride = out->get_size(0)*out->get_size(1)*out->get_size(2); 58 | 59 | auto cuRes = cufftPlanMany(&plan, 1,tdim.data(),tdim.data(),istride,1,tdim.data(),istride,1,CUFFT_C2R,istride); 60 | if (cuRes != CUFFT_SUCCESS) { 61 | std::stringstream ss; 62 | ss << "cuNDFFT FFT plan failed: " << cuRes; 63 | throw std::runtime_error(ss.str()); 64 | } 65 | 66 | auto result = cufftExecC2R(plan,(cufftComplex*) in->get_data_ptr(), (cufftReal*) out_tmp->get_data_ptr()); 67 | if (result != CUFFT_SUCCESS) { 68 | std::stringstream ss; 69 | ss << "cuNDFFT FFT plan failed: " << result; 70 | throw std::runtime_error(ss.str()); 71 | } 72 | 73 | *out_tmp *= 1.0f/std::sqrt(float(out->get_size(3))); 74 | if (accumulate){ 75 | *out += *out_tmp; 76 | delete out_tmp; 77 | } 78 | cufftDestroy(plan); 79 | 80 | } -------------------------------------------------------------------------------- /operators/cuTFFT.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 19/12/16. 3 | // 4 | 5 | #ifndef GT_TOMOGRAPHY_CUTFFT_H 6 | #define GT_TOMOGRAPHY_CUTFFT_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace Gadgetron { 13 | 14 | class cuTFFT : public linearOperator> { 15 | 16 | public: 17 | void mult_M(cuNDArray *, cuNDArray *, bool) override; 18 | 19 | void mult_MH(cuNDArray *, cuNDArray *, bool) override; 20 | 21 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions() override { 22 | auto res = this->get_domain_dimensions(); 23 | res->insert(res->begin(),2); 24 | //res->at(3) = res->at(3)+2; 25 | res->at(4) = res->at(4)/2+1; 26 | return res; 27 | } 28 | 29 | virtual void set_codomain_dimensions(std::vector* size) override { 30 | throw std::runtime_error("Cannot set codomain dimension on cuTFFT"); 31 | } 32 | 33 | 34 | }; 35 | 36 | } 37 | 38 | 39 | #endif //GT_TOMOGRAPHY_CUTFFT_H 40 | -------------------------------------------------------------------------------- /operators/cuTFFTPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTFFT.h" 5 | #include 6 | 7 | namespace Gadgetron { 8 | 9 | 10 | class cuTFFTPrimalDualOperator : public primalDualOperator> { 11 | 12 | public: 13 | virtual void primalDual(cuNDArray *in, cuNDArray *out, float sigma = 0, 14 | bool accumulate = false) override { 15 | 16 | auto data = cuNDArray(op.get_codomain_dimensions()); 17 | op.mult_M(in, &data, false); 18 | data *= sigma * this->get_weight(); 19 | 20 | auto dims = op.get_codomain_dimensions(); 21 | 22 | auto cdims = std::vector(dims->begin() + 1, dims->end()); //Copy cdims, excluding first dimension 23 | 24 | auto c_data = cuNDArray>(cdims, (complext *) data.get_data_ptr()); 25 | 26 | updateF(c_data, 0, sigma); 27 | op.mult_MH(&data, out, accumulate); 28 | 29 | 30 | } 31 | 32 | virtual void set_domain_dimensions(std::vector *dims) { 33 | op.set_domain_dimensions(dims); 34 | } 35 | 36 | private: 37 | cuTFFT op; 38 | 39 | }; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /operators/cuTV4DPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include "cuTVPrimalDualOperator.h" 5 | #include 6 | #include "cuGaussianFilterOperator.h" 7 | namespace Gadgetron { 8 | template 9 | class cuTV4DPrimalDualOperator : public cuTVPrimalDualOperator { 10 | typedef cuTVPrimalDualOperator parent; 11 | 12 | 13 | 14 | public: 15 | cuTV4DPrimalDualOperator() : parent() { 16 | 17 | } 18 | cuTV4DPrimalDualOperator( T alpha_ ) : parent(alpha_){ 19 | 20 | } 21 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override { 22 | 23 | if (!accumulate) clear(out); 24 | cuNDArray tmp_in = *in; 25 | cuNDArray tmp_out = *out; 26 | 27 | 28 | std::vector dim3D {in->get_size(0),in->get_size(1),in->get_size(2)}; 29 | size_t elements3D = in->get_size(0)*in->get_size(1)*in->get_size(2); 30 | 31 | for (int i =0; i < in->get_size(3); i++){ 32 | cuNDArray view_in(dim3D,tmp_in.get_data_ptr()+elements3D*i); 33 | cuNDArray view_in2(dim3D,in->get_data_ptr()+elements3D*((i+1)%in->get_size(3))); 34 | view_in -= view_in2; 35 | } 36 | 37 | parent::primalDual(&tmp_in,&tmp_out,sigma,false); 38 | 39 | *out += tmp_out; 40 | 41 | for (int i =0; i < in->get_size(3); i++){ 42 | cuNDArray view_out(dim3D,out->get_data_ptr()+elements3D*i); 43 | cuNDArray view_out2(dim3D,tmp_out.get_data_ptr()+elements3D*((i-1+in->get_size(3))%in->get_size(3))); 44 | view_out -= view_out2; 45 | } 46 | 47 | 48 | 49 | }; 50 | 51 | 52 | 53 | 54 | 55 | 56 | }; 57 | } -------------------------------------------------------------------------------- /operators/cuTVPrimalDualOperator.cu: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "cuTVPrimalDualOperator.h" 4 | #include "cuPartialDifferenceOperator.h" 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Gadgetron; 10 | template __global__ static void cuTVPrimalKernel(const T* __restrict__ in, T* __restrict__ out, vector_td dims, T omega,T weight){ 11 | 12 | const int elements = prod(dims); 13 | 14 | const int ix = blockIdx.x*blockDim.x+threadIdx.x; 15 | const int iy = blockIdx.y*blockDim.y+threadIdx.y; 16 | const int iz = blockIdx.z*blockDim.z+threadIdx.z; 17 | const auto co = vector_td(ix,iy,iz); 18 | vector_td result; 19 | if (co < dims){ 20 | auto val1 = in[co_to_idx(co,dims)]; 21 | auto co2 = co; 22 | for (int i = 0; i < 3; i++){ 23 | //co[DIM] = (co[DIM]+SKIP+dims[DIM])%dims[DIM]; 24 | 25 | co2[i] = (co[i]+dims[i]+1)%dims[i]; 26 | result[i] = in[co_to_idx(co2,dims)]-val1; 27 | co2[i] = co[i]; 28 | } 29 | result *= weight/(T(1.0)+omega); 30 | result /= max(T(1),norm(result)); 31 | const int idx = ix+iy*dims[0]+iz*dims[0]*dims[1]; 32 | for (int i =0; i < 3; i++) 33 | out[idx+i*elements] = result[i]; 34 | // atomicAdd(&out[idx+i*elements],result[i]); 35 | 36 | } 37 | 38 | }; 39 | 40 | 41 | template __global__ static void cuTVDualKernel(const T* __restrict__ in, T* __restrict__ out, vector_td dims,T weight){ 42 | 43 | const int elements = prod(dims); 44 | 45 | const int ix = blockIdx.x*blockDim.x+threadIdx.x; 46 | const int iy = blockIdx.y*blockDim.y+threadIdx.y; 47 | const int iz = blockIdx.z*blockDim.z+threadIdx.z; 48 | const auto co = vector_td(ix,iy,iz); 49 | 50 | if (co < dims){ 51 | const int idx = ix+iy*dims[0]+iz*dims[0]*dims[1]; 52 | T result = 0; 53 | auto co2 = co; 54 | for (int i = 0; i < 3; i++){ 55 | auto val1 = in[idx+i*elements]; 56 | 57 | co2[i] = (co[i]+dims[i]-1)%dims[i]; 58 | result += in[co_to_idx(co2,dims)+i*elements]-val1; 59 | co2[i] = co[i]; 60 | 61 | } 62 | // atomicAdd(&out[idx],result*weight); 63 | out[idx] += result*weight; 64 | } 65 | 66 | }; 67 | 68 | 69 | template void Gadgetron::cuTVPrimalDualOperator::primalDual(cuNDArray* in, cuNDArray* out, T sigma, bool accumulate){ 70 | 71 | if (!in->dimensions_equal(out)) 72 | throw std::runtime_error("Input and reference dimensions must agree"); 73 | 74 | if (!accumulate) clear(out); 75 | 76 | auto dims3D = std::vector{in->get_size(0),in->get_size(1),in->get_size(2)}; 77 | vector_td dims = vector_td(from_std_vector(dims3D)); 78 | 79 | 80 | dim3 threads(8, 8,8); 81 | dim3 grid((dims[0]+threads.x-1)/threads.x, (dims[1]+threads.y-1)/threads.y,(dims[2]+threads.z-1)/threads.z); 82 | 83 | T* data_in = in->get_data_ptr(); 84 | T* data_out = out->get_data_ptr(); 85 | 86 | auto dimsGrad3d = dims3D; 87 | dimsGrad3d.push_back(3); 88 | 89 | cuNDArray grad3D(dimsGrad3d); 90 | 91 | size_t remaining = 1; 92 | for (int i = 3; i < in->get_number_of_dimensions(); i++) remaining *= in->get_size(i); 93 | 94 | for (int i = 0; i < remaining; i++){ 95 | clear(&grad3D); 96 | 97 | cuTVPrimalKernel<<>>(data_in,grad3D.get_data_ptr(),dims,sigma*alpha,this->weight*sigma); 98 | cudaDeviceSynchronize(); 99 | 100 | cuTVDualKernel<<>>(grad3D.get_data_ptr(),data_out,dims,this->weight); 101 | data_in += prod(dims); 102 | data_out += prod(dims); 103 | } 104 | 105 | 106 | }; 107 | 108 | 109 | 110 | 111 | 112 | template class Gadgetron::cuTVPrimalDualOperator; 113 | -------------------------------------------------------------------------------- /operators/cuTVPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include 5 | namespace Gadgetron { 6 | template 7 | class cuTVPrimalDualOperator : public primalDualOperator> { 8 | 9 | 10 | public: 11 | cuTVPrimalDualOperator() : primalDualOperator>(), alpha(0),offset(1){} 12 | cuTVPrimalDualOperator(T alpha_ ) : primalDualOperator>(),alpha(alpha_){} 13 | void set_offset(int off){ offset = off;} 14 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override; 15 | 16 | 17 | 18 | private: 19 | T alpha; 20 | int offset; 21 | 22 | }; 23 | } -------------------------------------------------------------------------------- /operators/cuTVTFFT.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 19/12/16. 3 | // 4 | 5 | #ifndef GT_TOMOGRAPHY_CUTVTFFT_H 6 | #define GT_TOMOGRAPHY_CUTVTFFT_H 7 | 8 | #include 9 | 10 | #include 11 | #include "primalDualOperator.h" 12 | namespace Gadgetron { 13 | 14 | class cuTVTFFT : public primalDualOperator> { 15 | 16 | 17 | public: 18 | 19 | cuTVTFFT() : primalDualOperator() { 20 | Ft = cuTFFT(); 21 | TV = cuTVPrimalDualOperator(); 22 | 23 | } 24 | 25 | 26 | virtual void primalDual(cuNDArray* in, cuNDArray* out,float sigma, bool accumulate) override { 27 | 28 | cuNDArray tmp(Ft.get_codomain_dimensions()); 29 | Ft.mult_M(in,&tmp,false); 30 | { 31 | auto dim_order = std::vector{1,2,3,4,0}; 32 | 33 | auto tmp2 = permute(&tmp, &dim_order); 34 | tmp.reshape(tmp2->get_dimensions()); 35 | 36 | TV.primalDual(tmp2.get(), &tmp, sigma, false); 37 | } 38 | auto dim_order = std::vector{4,0,1,2,3}; 39 | 40 | auto tmp2 = permute(&tmp,&dim_order); 41 | Ft.mult_MH(tmp2.get(),out,accumulate); 42 | 43 | 44 | 45 | 46 | 47 | 48 | }; 49 | 50 | 51 | void set_domain_dimensions(std::vector *dims){ 52 | Ft.set_domain_dimensions(dims); 53 | } 54 | 55 | cuTVPrimalDualOperator TV; 56 | cuTFFT Ft; 57 | 58 | }; 59 | 60 | } 61 | 62 | 63 | #endif //GT_TOMOGRAPHY_CUTVTFFT_H 64 | -------------------------------------------------------------------------------- /operators/cuWTVPrimalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "primalDualOperator.h" 4 | #include 5 | namespace Gadgetron { 6 | template 7 | class cuWTVPrimalDualOperator : public primalDualOperator> { 8 | 9 | 10 | public: 11 | cuWTVPrimalDualOperator() : primalDualOperator>(), alpha(0),epsilon(1){} 12 | cuWTVPrimalDualOperator(T alpha_,T epsilon_ ) : primalDualOperator>(),alpha(alpha_), epsilon(epsilon_){} 13 | virtual void primalDual(cuNDArray* in, cuNDArray* out,T sigma, bool accumulate) override; 14 | 15 | virtual void update_weights(cuNDArray* x) override; 16 | 17 | 18 | 19 | private: 20 | T alpha; 21 | T epsilon; 22 | 23 | }; 24 | } -------------------------------------------------------------------------------- /operators/hoCuHaarWaveletOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoCuNDArray.h" 4 | #include "cuNDArray.h" 5 | #include "linearOperator.h" 6 | #include "cuHaarWaveletOperator.h" 7 | 8 | namespace Gadgetron{ 9 | 10 | template class hoCuHaarWaveletOperator : public linearOperator >{ 11 | 12 | public: 13 | hoCuHaarWaveletOperator() : linearOperator >(){}; 14 | 15 | virtual ~hoCuHaarWaveletOperator(){}; 16 | virtual void mult_M(hoCuNDArray* in ,hoCuNDArray* out,bool accumulate ){ 17 | cuNDArray cuIn(*in); 18 | cuNDArray cuOut(*out); 19 | 20 | cuHaar.mult_M(&cuIn,&cuOut,accumulate); 21 | 22 | cudaMemcpy(out->get_data_ptr(),cuOut.get_data_ptr(),cuOut.get_number_of_elements()*sizeof(T),cudaMemcpyDeviceToHost); 23 | 24 | } 25 | virtual void mult_MH(hoCuNDArray* in,hoCuNDArray* out ,bool accumulate){ 26 | cuNDArray cuIn(*in); 27 | cuNDArray cuOut(*out); 28 | 29 | cuHaar.mult_MH(&cuIn,&cuOut,accumulate); 30 | 31 | cudaMemcpy(out->get_data_ptr(),cuOut.get_data_ptr(),cuOut.get_number_of_elements()*sizeof(T),cudaMemcpyDeviceToHost); 32 | 33 | } 34 | virtual void mult_MH_M(hoCuNDArray* in ,hoCuNDArray* out,bool accumulate ){ 35 | if (accumulate){ 36 | *out += *in; 37 | } else { 38 | *out = *in; 39 | } 40 | } 41 | virtual boost::shared_ptr< linearOperator< hoCuNDArray > > clone(){ 42 | return linearOperator< hoCuNDArray >::clone(this); 43 | } 44 | virtual void set_domain_dimensions(std::vector* dims){ 45 | cuHaar.set_domain_dimensions(dims); 46 | } 47 | 48 | virtual boost::shared_ptr< std::vector > get_domain_dimensions(){ 49 | return cuHaar.get_domain_dimensions(); 50 | } 51 | 52 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(){ 53 | return cuHaar.get_codomain_dimensions(); 54 | } 55 | 56 | protected: 57 | cuHaarWaveletOperator cuHaar; 58 | }; 59 | 60 | } 61 | -------------------------------------------------------------------------------- /operators/hoCuPartialDerivativeOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "partialDerivativeOperator.h" 4 | #include "cuPartialDerivativeOperator.h" 5 | #include "hoCuNDArray.h" 6 | #include "cudaDeviceManager.h" 7 | #include "cuNDArray_operators.h" 8 | #include "cuNDArray_elemwise.h" 9 | 10 | #include "hoPartialDerivativeOperator.h" 11 | 12 | namespace Gadgetron{ 13 | 14 | template class hoCuPartialDerivativeOperator : 15 | public linearOperator > 16 | { 17 | public: 18 | 19 | hoCuPartialDerivativeOperator() : 20 | linearOperator >(),dev(),hoDev(),_dimension(0) {} 21 | 22 | hoCuPartialDerivativeOperator( unsigned int dimension ) : 23 | linearOperator >(),dev(dimension),hoDev(dimension), _dimension(dimension){ } 24 | 25 | virtual ~hoCuPartialDerivativeOperator() {} 26 | 27 | virtual boost::shared_ptr< linearOperator > > clone() { 28 | return linearOperator >::clone(this); 29 | } 30 | 31 | //TODO: Generalize to work if we can fit just the 1 single dimension on the gpu 32 | virtual void mult_M(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) 33 | { 34 | size_t free = cudaDeviceManager::Instance()->getFreeMemory(); 35 | 36 | if( free/sizeof(T) < in->get_number_of_elements()*2) 37 | throw std::runtime_error("hoCuPartialDerivativeOperator: not enough device memory"); 38 | cuNDArray cuIn(in); 39 | cuNDArray cuOut(out->get_dimensions()); 40 | 41 | if (accumulate) cuOut =cuNDArray(out); 42 | 43 | dev.mult_M(&cuIn,&cuOut,accumulate); 44 | 45 | cudaMemcpy(out->get_data_ptr(),cuOut.get_data_ptr(),out->get_number_of_elements()*sizeof(T),cudaMemcpyDeviceToHost); 46 | //hoDev.mult_M(in,out,accumulate); 47 | } 48 | 49 | //TODO: Generalize to work if we can fit just the 1 single dimension on the gpu 50 | virtual void mult_MH(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) 51 | { 52 | 53 | size_t free = cudaDeviceManager::Instance()->getFreeMemory(); 54 | 55 | if( free/sizeof(T) < in->get_number_of_elements()*2) 56 | throw std::runtime_error("hoCuPartialDerivativeOperator: not enough device memory"); 57 | cuNDArray cuIn(in); 58 | cuNDArray cuOut(out->get_dimensions()); 59 | 60 | if (accumulate) cuOut =cuNDArray(out); 61 | 62 | dev.mult_MH(&cuIn,&cuOut,accumulate); 63 | 64 | cudaMemcpy(out->get_data_ptr(),cuOut.get_data_ptr(),out->get_number_of_elements()*sizeof(T),cudaMemcpyDeviceToHost); 65 | 66 | //hoDev.mult_MH(in,out,accumulate); 67 | } 68 | 69 | //TODO: Generalize to work if we can fit just the 1 single dimension on the gpu 70 | virtual void mult_MH_M(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) 71 | { 72 | 73 | size_t free = cudaDeviceManager::Instance()->getFreeMemory(); 74 | 75 | if( free/sizeof(T) < in->get_number_of_elements()*2) 76 | throw std::runtime_error("hoCuPartialDerivativeOperator: not enough device memory"); 77 | cuNDArray cuIn(in); 78 | cuNDArray cuOut(out->get_dimensions()); 79 | 80 | if (accumulate) cuOut =cuNDArray(out); 81 | 82 | dev.mult_MH_M(&cuIn,&cuOut,accumulate); 83 | 84 | cudaMemcpy(out->get_data_ptr(),cuOut.get_data_ptr(),out->get_number_of_elements()*sizeof(T),cudaMemcpyDeviceToHost); 85 | 86 | //hoDev.mult_MH_M(in,out,accumulate); 87 | } 88 | 89 | protected: 90 | cuPartialDerivativeOperator dev; 91 | hoPartialDerivativeOperator hoDev; 92 | unsigned int _dimension; 93 | }; 94 | } 95 | -------------------------------------------------------------------------------- /operators/invertibleOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * invertibleOperator.h 3 | * 4 | * Created on: Jul 5, 2015 5 | * Author: u051747 6 | */ 7 | #pragma once 8 | #include "linearOperator.h" 9 | namespace Gadgetron { 10 | 11 | template class invertibleOperator : public linearOperator { 12 | 13 | public: 14 | virtual void inverse(ARRAY* in,ARRAY* out, bool accumulate = true) = 0; 15 | }; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /operators/linearToSubsetOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * linearToSubsetOperator.h 3 | * 4 | * Created on: Nov 27, 2015 5 | * Author: dch 6 | */ 7 | 8 | #ifndef LINEARTOSUBSETOPERATOR_H_ 9 | #define LINEARTOSUBSETOPERATOR_H_ 10 | #include "subsetOperator.h" 11 | 12 | namespace Gadgetron{ 13 | template class linearToSubsetOperator : public subsetOperator { 14 | 15 | public: 16 | linearToSubsetOperator(boost::shared_ptr> op): subsetOperator(), op_(op){ 17 | 18 | } 19 | 20 | virtual void mult_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate) override { 21 | return op_->mult_M(in,out,accumulate); 22 | } 23 | virtual void mult_MH(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate) override { 24 | return op_->mult_MH(in,out,accumulate); 25 | } 26 | virtual void mult_MH_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate) override{ 27 | return op_->mult_MH_M(in,out,accumulate); 28 | } 29 | 30 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(int subset) override { 31 | return op_->get_codomain_dimensions(); 32 | } 33 | 34 | 35 | private: 36 | boost::shared_ptr> op_; 37 | 38 | 39 | }; 40 | } 41 | 42 | 43 | 44 | #endif /* LINEARTOSUBSETOPERATOR_H_ */ 45 | -------------------------------------------------------------------------------- /operators/primalDualOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Gadgetron { 5 | template 6 | class primalDualOperator { 7 | 8 | public: 9 | typedef typename ARRAY::element_type ELEMENT_TYPE; 10 | typedef typename realType::Type REAL; 11 | virtual void primalDual(ARRAY* in,ARRAY *out, REAL sigma = 0, bool accumulate = false)=0; 12 | 13 | virtual void set_weight(REAL weight_){ weight = weight_;} 14 | virtual REAL get_weight(){ return weight;} 15 | 16 | primalDualOperator() : weight(1) { }; 17 | 18 | virtual void update_weights(ARRAY* x){}; 19 | 20 | protected: 21 | REAL weight; 22 | boost::shared_ptr weight_arr; 23 | 24 | 25 | }; 26 | } -------------------------------------------------------------------------------- /operators/projectionSpaceOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperator.h" 3 | #include 4 | 5 | namespace Gadgetron{ 6 | template class projectionSpaceOperator : public linearOperator{ 7 | public: 8 | projectionSpaceOperator(boost::shared_ptr > _op) : linearOperator(), op(_op){}; 9 | projectionSpaceOperator() : linearOperator() {}; 10 | void set_projections(boost::shared_ptr _projections){projections = _projections;} 11 | virtual ~projectionSpaceOperator(){}; 12 | virtual void mult_M(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate=false){ 13 | op->mult_M(in,out,accumulate); 14 | } 15 | virtual void mult_MH(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate=false){ 16 | op->mult_M(in,out,accumulate); 17 | } 18 | 19 | virtual void mult_MH_M(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate=false){ 20 | op->mult_M(in,out,accumulate); 21 | } 22 | 23 | /** 24 | * The gradient of a linear operator corresponds to mult_MH_M. 25 | * @param[in] in Input array. 26 | * @param[in,out] out Output Array. 27 | * @param accumulate If true, adds result to out. If false, overwrites out. 28 | */ 29 | virtual void gradient(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate = false) 30 | { 31 | if( in == 0x0 || out == 0x0 ) 32 | throw std::runtime_error("linearOperator::gradient(): Invalid input and/or output array"); 33 | 34 | ARRAY_TYPE* tmp = out; 35 | if (accumulate) { 36 | tmp = new ARRAY_TYPE(out->get_dimensions()); 37 | } 38 | 39 | ARRAY_TYPE pSpace(projections->get_dimensions()); 40 | 41 | this->mult_M(in,&pSpace,false); 42 | pSpace -= *projections; 43 | this->mult_MH(&pSpace,tmp,false); 44 | 45 | *tmp *= this->weight_; 46 | if (accumulate){ 47 | *out += *tmp; 48 | delete tmp; 49 | } 50 | } 51 | 52 | 53 | protected: 54 | 55 | boost::shared_ptr > op; 56 | 57 | boost::shared_ptr projections; 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /operators/subselectionOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperator.h" 3 | #include 4 | #include 5 | namespace Gadgetron { 6 | 7 | template class subselectionOperator : public linearOperator { 8 | 9 | public: 10 | 11 | subselectionOperator(boost::shared_ptr > op_, unsigned int subview_ = 0) : linearOperator(), op(op_), subview(subview_) {} 12 | 13 | virtual void mult_M(ARRAY* in, ARRAY* out, bool accumulate = false) override { 14 | auto dims = *in->get_dimensions(); 15 | auto dims2 = dims; 16 | dims2.pop_back(); 17 | 18 | size_t elements = std::accumulate(dims2.begin(),dims2.end(),1,std::multiplies()); 19 | ARRAY view(dims2,in->get_data_ptr()+elements*subview); 20 | op->mult_M(&view,out,accumulate); 21 | 22 | } 23 | 24 | virtual void mult_MH(ARRAY* in, ARRAY* out, bool accumulate = false) override { 25 | auto dims = *out->get_dimensions(); 26 | auto dims2 = dims; 27 | dims2.pop_back(); 28 | 29 | size_t elements = std::accumulate(dims2.begin(),dims2.end(),1,std::multiplies()); 30 | ARRAY out_view(dims2,out->get_data_ptr()+elements*subview); 31 | if (!accumulate) 32 | clear(out); 33 | op->mult_MH(in,&out_view,accumulate); 34 | 35 | 36 | } 37 | 38 | virtual void mult_MH_M(ARRAY* in, ARRAY *out, bool accumulate=false) override { 39 | auto dims = *out->get_dimensions(); 40 | auto dims2 = dims; 41 | dims2.pop_back(); 42 | 43 | size_t elements = std::accumulate(dims2.begin(),dims2.end(),1,std::multiplies()); 44 | ARRAY out_view(dims2,out->get_data_ptr()+elements*subview); 45 | ARRAY in_view(dims2,in->get_data_ptr()+elements*subview); 46 | if (!accumulate) 47 | clear(out); 48 | op->mult_MH_M(&in_view,&out_view,accumulate); 49 | 50 | 51 | } 52 | 53 | protected: 54 | boost::shared_ptr> op; 55 | unsigned int subview; 56 | }; 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /operators/subsetAccumulateOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "subsetOperator.h" 4 | 5 | namespace Gadgetron { 6 | 7 | template class subsetAccumulateOperator : public subsetOperator{ 8 | public: 9 | subsetAccumulateOperator(boost::shared_ptr > op_, unsigned int splits_) : subsetOperator(), op(op_), splits(splits_){ 10 | this->number_of_subsets = op->get_number_of_subsets(); 11 | } 12 | 13 | virtual void mult_M(ARRAY* in, ARRAY* out, int subset, bool accumulate = false ) override { 14 | 15 | auto dims = *in->get_dimensions(); 16 | auto back_dim = dims.back(); 17 | dims.pop_back(); 18 | 19 | ARRAY tmp(dims); 20 | clear(&tmp); 21 | auto elements = tmp.get_number_of_elements(); 22 | 23 | for (auto i =0u; i < back_dim; i++){ 24 | ARRAY view(dims,in->get_data_ptr()+elements*i); 25 | tmp += view; 26 | } 27 | 28 | op->mult_M(&tmp,out,subset,accumulate); 29 | 30 | 31 | //ARRAY tmp(dims,in->get_data_ptr()); 32 | //op->mult_M(&tmp,out,subset,accumulate); 33 | } 34 | 35 | virtual boost::shared_ptr< std::vector > get_domain_dimensions() override { 36 | auto dims = op->get_domain_dimensions(); 37 | dims->push_back(splits); 38 | return dims; 39 | } 40 | 41 | 42 | virtual void mult_MH(ARRAY* in, ARRAY* out, int subset, bool accumulate = false ) override { 43 | 44 | auto dims = *out->get_dimensions(); 45 | auto back_dim = dims.back(); 46 | dims.pop_back(); 47 | 48 | ARRAY tmp(dims); 49 | auto elements = tmp.get_number_of_elements(); 50 | op->mult_MH(in,&tmp,subset,false); 51 | if (!accumulate) clear(out); 52 | for (auto i =0u; i < back_dim; i++){ 53 | ARRAY view(dims,out->get_data_ptr()+elements*i); 54 | view += tmp; 55 | } 56 | 57 | 58 | //ARRAY tmp(dims,out->get_data_ptr()); 59 | //op->mult_MH(in,&tmp,subset,accumulate); 60 | 61 | } 62 | 63 | 64 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(int subset) override{ 65 | return op->get_codomain_dimensions(subset); 66 | } 67 | 68 | virtual int get_number_of_subsets() override {return op->get_number_of_subsets();} 69 | 70 | protected: 71 | boost::shared_ptr> op; 72 | unsigned int splits; 73 | }; 74 | } 75 | -------------------------------------------------------------------------------- /operators/subsetConverter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "subsetOperator.h" 4 | #include 5 | namespace Gadgetron { 6 | 7 | 8 | template class subsetConverter : public subsetOperator { 9 | public: 10 | subsetConverter(boost::shared_ptr> op_) : subsetOperator(), op(op_) { 11 | 12 | }; 13 | 14 | virtual ~subsetConverter(){}; 15 | virtual void mult_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 16 | op->mult_M(in,out,accumulate); 17 | } 18 | virtual void mult_MH(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 19 | op->mult_MH(in,out,accumulate); 20 | } 21 | virtual void mult_MH_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 22 | op->mult_MH_M(in,out,accumulate); 23 | } 24 | 25 | 26 | virtual boost::shared_ptr< std::vector > get_domain_dimensions(int subset){ 27 | return op->get_domain_dimensions(); 28 | } 29 | 30 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(int subset){ 31 | return op->get_codomain_dimensions(); 32 | } 33 | protected: 34 | boost::shared_ptr> op; 35 | 36 | 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /operators/weightingOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "linearOperator.h" 4 | namespace Gadgetron{ 5 | 6 | template class weightingOperator: public linearOperator{ 7 | public: 8 | weightingOperator(): linearOperator(){}; 9 | weightingOperator(boost::shared_ptr _weights,boost::shared_ptr> _op): linearOperator(), weights(_weights), op(_op){}; 10 | 11 | virtual void set_weights(boost::shared_ptr _weights){ 12 | weights = _weights; 13 | } 14 | 15 | virtual void mult_M(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate=false){ 16 | if (accumulate){ 17 | ARRAY_TYPE tmp = *out; 18 | op->mult_M(in,&tmp); 19 | tmp *= *weights; 20 | *out += tmp; 21 | } else{ 22 | op->mult_M(in,out); 23 | *out *= *weights; 24 | } 25 | } 26 | 27 | virtual void mult_MH(ARRAY_TYPE* in, ARRAY_TYPE* out, bool accumulate=false){ 28 | ARRAY_TYPE tmp = *in; 29 | tmp *= *weights; 30 | op->mult_MH(&tmp,out,accumulate); 31 | } 32 | 33 | protected: 34 | boost::shared_ptr weights; 35 | boost::shared_ptr> op; 36 | }; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /proton/circulantPreconditioner.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "circulantPreconditioner.h" 5 | 6 | 7 | using namespace Gadgetron; 8 | 9 | #include "cuNDFFT.h" 10 | #include "hoNDFFT.h" 11 | 12 | 13 | template void circulantPreconditioner::apply(ARRAY * in, ARRAY * out){ 14 | //boost::shared_ptr<>real_to_complex(in) 15 | real_to_complex() 16 | //FFTInstance::instance()-> 17 | convolutionOperator 18 | } 19 | -------------------------------------------------------------------------------- /proton/circulantPreconditioner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray.h" 4 | #include "cuNDArray.h" 5 | #include "cgPreconditioner.h" 6 | 7 | #include "linearOperator.h" 8 | 9 | #include "cuNDFFT.h" 10 | #include "hoNDFFT.h" 11 | #include "hoNDArray_math.h" 12 | #include "cuNDArray_math.h" 13 | 14 | namespace Gadgetron{ 15 | 16 | 17 | 18 | template struct FFTInstance{}; 19 | 20 | template struct FFTInstance >{ 21 | static cuNDFFT* instance(){ 22 | return cuNDFFT::instance(); 23 | } 24 | }; 25 | template struct FFTInstance >{ 26 | static hoNDFFT* instance(){ 27 | return hoNDFFT::instance(); 28 | } 29 | }; 30 | 31 | 32 | 33 | template class ARRAY, class T> class circulantPreconditioner: public cgPreconditioner > { 34 | 35 | public: 36 | 37 | circulantPreconditioner(boost::shared_ptr< linearOperator > > op) : cgPreconditioner >(), op_(op) { 38 | 39 | kernel_ = calcKernel(); 40 | 41 | } 42 | 43 | 44 | virtual ~circulantPreconditioner(){}; 45 | virtual void apply(ARRAY * in, ARRAY * out){ 46 | std::cout <<"Preconditionaaa-buruuu!" << std::endl; 47 | ARRAY tmp(*in); 48 | save_nd_array(&tmp,"in.real"); 49 | boost::shared_ptr > > cplx = real_to_complex >(in); 50 | FFTInstance >::instance()->fft(cplx.get()); 51 | std::cout <<"FFT-buruu!" << std::endl; 52 | *cplx *= *kernel_; 53 | FFTInstance >::instance()->ifft(cplx.get()); 54 | 55 | *out = *real(cplx.get()); 56 | save_nd_array(out,"kernel.real"); 57 | 58 | std::cout <<"Done-buruu!" << std::endl; 59 | } 60 | 61 | protected: 62 | 63 | 64 | boost::shared_ptr< linearOperator > > op_; 65 | boost::shared_ptr > > kernel_; 66 | 67 | boost::shared_ptr > > calcKernel(){ 68 | std::vector dims = *op_->get_domain_dimensions(); 69 | std::vector central_element; 70 | for (size_t i = 0; i < dims.size(); i++){ 71 | central_element.push_back(dims[i]/2); 72 | std::cout << " " < real_kernel(dims); 80 | { 81 | hoNDArray ho_one(dims); 82 | clear(&ho_one); 83 | 84 | size_t central_id = 0; 85 | size_t stride = 1; 86 | for (size_t i = 0; i < dims.size(); i++){ 87 | central_id += stride*central_element[i]; 88 | stride *= dims[i]; 89 | } 90 | ho_one.get_data_ptr()[central_id] = T(1); 91 | 92 | 93 | ARRAY one(&ho_one); 94 | std::cout << "Applying the operAaaator" << std::endl; 95 | op_->mult_MH_M(&one,&real_kernel); 96 | } 97 | 98 | 99 | boost::shared_ptr > > kernel = real_to_complex >(&real_kernel); 100 | 101 | std::cout << "Doing FFT" << std::endl; 102 | FFTInstance >::instance()->fft(kernel.get()); 103 | reciprocal_inplace(kernel.get()); 104 | sqrt_inplace(kernel.get()); 105 | return kernel; 106 | } 107 | }; 108 | } 109 | -------------------------------------------------------------------------------- /proton/hdf5_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hdf5_utils.h 3 | * 4 | * Created on: Dec 3, 2012 5 | * Author: Dae 6 | */ 7 | 8 | #pragma once 9 | #include "hoNDArray.h" 10 | #include "hdf5.h" 11 | #include "hdf5_hl.h" 12 | #include 13 | 14 | namespace Gadgetron{ 15 | 16 | 17 | template void saveNDArray2HDF5(hoNDArray* input,std::string filename,vector_td dimensions, vector_td origin, std::string arguements, unsigned int iterations){ 18 | /* Create a new file using default properties. */ 19 | hid_t file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 20 | 21 | size_t ndims = input->get_number_of_dimensions(); 22 | 23 | std::vector dims(ndims); 24 | 25 | for (int i = 0; i < ndims; i++) dims[i] = input->get_size(ndims-i-1); 26 | H5LTmake_dataset (file_id, "/image", ndims, dims.data(), H5T_NATIVE_FLOAT, input->get_data_ptr()); 27 | H5LTset_attribute_string(file_id,"/image","input",arguements.c_str()); 28 | 29 | H5LTset_attribute_float(file_id,"/image","dimensions",dimensions.vec,D); 30 | vector_td element_size_um; 31 | for (int i = 0; i < D; i++){ 32 | element_size_um[D-i-1] = dimensions[i]/input->get_size(i); 33 | } 34 | H5LTset_attribute_float(file_id,"/image","element_size_um",element_size_um.vec,D); 35 | H5LTset_attribute_float(file_id,"/image","origin",origin.vec,D); 36 | H5LTset_attribute_uint(file_id,"/image","iterations",&iterations,1); 37 | 38 | 39 | H5Fclose(file_id); 40 | } 41 | 42 | template void saveNDArray2HDF5(cuNDArray* input,std::string filename,vector_td dimensions, vector_td origin, std::string arguements, unsigned int iterations){ 43 | boost::shared_ptr > tmp = input->to_host(); 44 | saveNDArray2HDF5(tmp.get(),filename,dimensions,origin,arguements,iterations); 45 | } 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /proton/histogram.cu: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "histogram.h" 17 | 18 | texture texRef; 19 | 20 | using namespace Gadgetron; 21 | 22 | 23 | template __global__ void parzen_kernel(T* data,float * parzen, 24 | const float sigma, const float start, const float end, const int bins, const int size){ 25 | typedef typename realType::type REAL; 26 | 27 | extern __shared__ T work_data[]; 28 | 29 | int bin = threadIdx.x+blockIdx.y*blockDim.x; 30 | float res = 0; 31 | float val = bin*(start-end)/bins+start; 32 | float sigma2 = sigma*sigma; 33 | int idx = threadIdx.x+blockIdx.x*blockDim.x; 34 | 35 | if (idx < size) work_data[threadIdx.x] = data[idx]; 36 | __syncthreads(); 37 | 38 | for (int i = 0; i < blockDim.x-(idx/size)*(idx%size); i++) { 39 | res += exp(-(val-work_data)*(val-work_data)/sigma2); 40 | } 41 | 42 | atomicAdd(&(parzen[bin]),res); 43 | } 44 | 45 | 46 | template boost::shared_ptr > parzen_grid(cuNDArray * data, int bins, float sigma, float& start, float & end ){ 47 | 48 | int blockSize =128; 49 | dim3 gridSize((data->get_number_of_elements()-1)/blockSize+1,(bins-1)/blockSize+1); 50 | 51 | start = thrust::min_element(data->begin(),data->end()); 52 | end = thrust::max_element(data->begin(),data->end()); 53 | 54 | std::vector pdims; 55 | pdims.push_back(bins); 56 | boost::shared_ptr > parzen(new cuNDArray(&pdims)); 57 | parzen_kernel<<>>(data->get_data_ptr(),parzen->get_data_ptr(),sigma,start,end,bins,data->get_number_of_elements()); 58 | 59 | return parzen; 60 | } 61 | 62 | 63 | template __global__ void entropy_kernel(T* data,float * parzen,float* result, int size, float start, float stop){ 64 | typedef typename realType::type REAL; 65 | 66 | extern __shared__ float work_data[]; 67 | int idx = threadIdx.x+blockIdx.x*blockDim.x; 68 | if (idx < size){ 69 | float p = tex1D(texRef,(float(data[idx])-start)/(stop-start)); 70 | work_data[threadIdx.x] = p*log2(p); 71 | __syncthreads(); 72 | for(int offset = blockDim.x / 2; offset > 0; offset /= 2) 73 | { 74 | if(threadIdx.x < offset) 75 | { 76 | work_data[threadIdx.x] += work_data[threadIdx.x + offset]; 77 | } 78 | __syncthreads(); 79 | } 80 | 81 | 82 | } 83 | if (threadIdx.x == 0) atomicAdd(result,work_data[0]); 84 | 85 | 86 | } 87 | 88 | 89 | template float entropy(cuNDArray * data, int bins, float sigma){ 90 | float start,end; 91 | boost::shared_ptr > grid = parzen_grid(data,bins,sigma,start, end); 92 | int blockSize =128; 93 | int gridSize = (data->get_number_of_elements()-1)/blockSize+1; 94 | 95 | texRef.filterMode = cudaFilterModeLinear; 96 | texRef.normalized = true; 97 | size_t offset; 98 | cudaBindTexture(&offset,texRef,grid->get_data_ptr(),grid->get_number_of_elements()); 99 | thrust::device_vector result_vec(1,0.0f); 100 | float* dev_result = thrust::raw_pointer_cast( &result_vec[0] ); 101 | entropy_kernel<<>>(data->get_data_ptr(),grid->get_data_ptr(),sigma,start,end,bins,data->get_number_of_elements()); 102 | 103 | return result_vec[0]; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /proton/histogram.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuNDArray.h" 4 | 5 | namespace Gadgetron{ 6 | 7 | 8 | template void impulse_kernel(cuNDArray* x, cuNDArray* histogram, T&, T& ); 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /proton/hoCuParallelProjection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoCuNDArray.h" 4 | #include "cuNDArray.h" 5 | #include "vector_td.h" 6 | 7 | namespace Gadgetron { 8 | void parallel_backprojection(hoCuNDArray* projections, cuNDArray* image, float angle, floatd3 image_dims, floatd3 projection_dims); 9 | void parallel_backprojection(cuNDArray* projections, cuNDArray* image, float angle, floatd3 image_dims, floatd3 projection_dims); 10 | void interpolate_missing( cuNDArray* image ); 11 | } 12 | -------------------------------------------------------------------------------- /proton/protonForwardProject.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * protonForwardProject.cpp 3 | * 4 | * Created on: Jan 3, 2012 5 | * Author: u051747 6 | */ 7 | 8 | 9 | #include 10 | #include "parameterparser.h" 11 | #include "cuNDArray.h" 12 | #include "cuCgSolver.h" 13 | #include "ndarray_vector_td_utilities.h" 14 | #include "cuOperatorPathBackprojection.h" 15 | #include "hoNDArray_fileio.h" 16 | #include 17 | using namespace std; 18 | typedef float _real; 19 | 20 | using namespace Gadgetron; 21 | 22 | 23 | int main( int argc, char** argv) 24 | { 25 | _real background = 0.00106; 26 | // 27 | // Parse command line 28 | // 29 | 30 | ParameterParser parms; 31 | parms.add_parameter( 'p', COMMAND_LINE_STRING, 1, "Input image file name (.real)", true,"phantom.real" ); 32 | parms.add_parameter( 's', COMMAND_LINE_STRING, 1, "Splines projection file name (.real)", true,"splines.real" ); 33 | parms.add_parameter( 'f', COMMAND_LINE_STRING, 1, "Output projection file name ", true,"projections.real" ); 34 | 35 | 36 | parms.add_parameter( 'x', COMMAND_LINE_FLOAT, 1, "X size (cm)", true, "1.0" ); 37 | parms.add_parameter( 'y', COMMAND_LINE_FLOAT, 1, "Y size (cm)", true, "1.0" ); 38 | parms.add_parameter( 'z', COMMAND_LINE_FLOAT, 1, "Z size (cm)", true, "1.0" ); 39 | 40 | parms.parse_parameter_list(argc, argv); 41 | if( parms.all_required_parameters_set() ){ 42 | cout << " Running reconstruction with the following parameters: " << endl; 43 | parms.print_parameter_list(); 44 | } 45 | else{ 46 | cout << " Some required parameters are missing: " << endl; 47 | parms.print_parameter_list(); 48 | parms.print_usage(); 49 | return 1; 50 | } 51 | 52 | 53 | boost::shared_ptr > > host_splines = read_nd_array< vector_td<_real,3> >((char*)parms.get_parameter('s')->get_string_value()); 54 | boost::shared_ptr > > splines (new cuNDArray< vector_td<_real,3> >(host_splines.get())); 55 | 56 | boost::shared_ptr< hoNDArray<_real> > host_phantom = read_nd_array<_real >((char*)parms.get_parameter('p')->get_string_value()); 57 | boost::shared_ptr > phantom (new cuNDArray<_real >(host_phantom.get())); 58 | 59 | 60 | vector_td<_real,3> physical_dims; 61 | vector ndims; 62 | ndims.push_back(3); 63 | 64 | 65 | physical_dims.vec[0]= (_real) parms.get_parameter('x')->get_float_value(); 66 | physical_dims.vec[1]= (_real) parms.get_parameter('y')->get_float_value(); 67 | physical_dims.vec[2]= (_real) parms.get_parameter('z')->get_float_value(); 68 | 69 | 70 | 71 | 72 | boost::shared_ptr< cuOperatorPathBackprojection<_real> > E (new cuOperatorPathBackprojection<_real> ); 73 | cout << "Performing setup" << endl; 74 | 75 | // 76 | 77 | boost::shared_ptr > projections = boost::shared_ptr >(new cuNDArray<_real>); 78 | vector projection_dims; 79 | projection_dims.push_back(splines->get_dimensions()->at(0)/4); 80 | 81 | projections->create(&projection_dims); 82 | projections->clear(); 83 | E->setup(splines,physical_dims,projections,background); 84 | projections->abs(); 85 | cout << "Starting forward projection" << endl; 86 | E->mult_M(phantom.get(),projections.get()); 87 | 88 | 89 | boost::shared_ptr< hoNDArray<_real> > host_result = projections->to_host(); 90 | write_nd_array<_real>(host_result.get(), (char*)parms.get_parameter('f')->get_string_value()); 91 | cout <<" AAAAND, done" << endl; 92 | } 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /proton/protonPreconditioner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray.h" 4 | #include "cuNDArray.h" 5 | #include "cgPreconditioner.h" 6 | 7 | namespace Gadgetron{ 8 | 9 | class protonPreconditioner: public cgPreconditioner > { 10 | 11 | public: 12 | 13 | protonPreconditioner(std::vector dims) : cgPreconditioner >() { 14 | 15 | uint64d2 vdims; 16 | vdims[0] = dims[0]; 17 | vdims[1] = dims[1]; 18 | angles = 720; 19 | kernel_ = calcKernel(vdims,angles); 20 | 21 | } 22 | 23 | virtual void apply(cuNDArray * in, cuNDArray * out); 24 | 25 | virtual void set_hull(boost::shared_ptr > hull){hull_ = hull;} 26 | protected: 27 | 28 | unsigned int angles; 29 | boost::shared_ptr > kernel_; 30 | 31 | boost::shared_ptr > hull_; 32 | static boost::shared_ptr > calcKernel(uint64d2 dims, int angles); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /proton/protonSubsetOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "subsetOperator.h" 3 | #include "hoCuNDArray.h" 4 | #include "splineBackprojectionOperator.h" 5 | #include "hdf5.h" 6 | #include "hdf5_hl.h" 7 | #include 8 | #include 9 | #include 10 | 11 | /** 12 | * This class is inconsistent, messy and requires polish. It's also suspected to be unreliable 13 | */ 14 | namespace Gadgetron{ 15 | template class ARRAY> class protonSubsetOperator : public subsetOperator >{ 16 | 17 | public: 18 | protonSubsetOperator() : subsetOperator >(1){ 19 | 20 | } 21 | protonSubsetOperator(std::vector< boost::shared_ptr< protonDataset > > datasets, floatd3 physical_dims ) : subsetOperator >(datasets.size()){ 22 | for (unsigned int i = 0; i < datasets.size(); i++){ 23 | operators.push_back(splineBackprojectionOperator(datasets[i],physical_dims)); 24 | subset_dimensions.push_back(datasets[i]->get_projections()->get_dimensions()); 25 | } 26 | 27 | } 28 | 29 | virtual ~protonSubsetOperator(){}; 30 | 31 | 32 | virtual void mult_M(ARRAY* in, ARRAY* out, int subset, bool accumulate=false){ 33 | std::stringstream ss; 34 | ss << "Subset " << subset << " out of bounds"; 35 | if (subset >= operators.size() ) throw std::runtime_error(ss.str()); 36 | operators[subset].mult_M(in,out,accumulate); 37 | } 38 | virtual void mult_MH(ARRAY* in, ARRAY* out, int subset, bool accumulate=false){ 39 | std::stringstream ss; 40 | ss << "Subset " << subset << " out of bounds"; 41 | if (subset >= operators.size() ) throw std::runtime_error(ss.str()); 42 | operators[subset].mult_MH(in,out,accumulate); 43 | } 44 | virtual void mult_MH_M(ARRAY* in, ARRAY* out, int subset, bool accumulate=false){ 45 | if (subset >= operators.size() ) throw std::runtime_error("Subset out of bounds"); 46 | operators[subset].mult_MH_M(in,out,accumulate); 47 | } 48 | 49 | virtual void protonCount(ARRAY* count_img, int subset){ 50 | std::stringstream ss; 51 | ss << "Subset " << subset << " out of bounds"; 52 | if (subset >= operators.size() ) throw std::runtime_error(ss.str()); 53 | operators[subset].protonCount(count_img); 54 | } 55 | 56 | virtual void pathNorm(ARRAY* projections, int subset ){ 57 | std::stringstream ss; 58 | ss << "Subset " << subset << " out of bounds"; 59 | if (subset >= operators.size() ) throw std::runtime_error(ss.str()); 60 | operators[subset].pathNorm(projections); 61 | } 62 | 63 | virtual void pathNorm(ARRAY* out){ 64 | std::vector > > projections = this->projection_subsets(out); 65 | for (int i = 0; i < operators.size(); i++) pathNorm(projections[i].get(),i); 66 | } 67 | 68 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(int subset){ 69 | return subset_dimensions[subset]; 70 | } 71 | 72 | virtual void set_domain_dimensions(std::vector * dims){ 73 | subsetOperator >::set_domain_dimensions(dims); 74 | for (int i = 0; i < operators.size(); i++) operators[i].set_domain_dimensions(dims); 75 | 76 | } 77 | 78 | protected: 79 | 80 | struct Spline{ 81 | float x,y,z,x2,y2,z2; 82 | float dirx,diry,dirz,dirx2,diry2,dirz2; 83 | }; 84 | 85 | 86 | 87 | std::vector< splineBackprojectionOperator > operators; 88 | std::vector > > subset_dimensions; 89 | 90 | }; 91 | } 92 | -------------------------------------------------------------------------------- /proton/proton_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray.h" 3 | 4 | #include "protonDataset.h" 5 | namespace Gadgetron{ 6 | 7 | void rotate_splines(cuNDArray * splines,float angle); 8 | 9 | 10 | /** 11 | * 12 | * @param[in] image Input image to project 13 | * @param[out] projections Output array to contain projections 14 | * @param[in] splines Array containing the information for the cubic splines 15 | * @param[in] phys_dims Physical dimensions of the image in cm 16 | * @param[in] exterior_path_lengths Array containing length from starting position to hull 17 | */ 18 | template class ARRAY> void protonProjection(ARRAY* image,ARRAY* projections, ARRAY* splines, floatd3 phys_dims,ARRAY* exterior_path_lengths=NULL ); 19 | 20 | /** 21 | * 22 | * @param[out] image Image to backproject into 23 | * @param[in] projections Proton projections to backproject 24 | * @param[in] splines Array containing the information for the cubic splines 25 | * @param[in] phys_dims Physical dimensions of the image in cm 26 | * @param[in] exterior_path_lengths Array containing length from starting position to hull 27 | */ 28 | template class ARRAY> void protonBackprojection(ARRAY* image,ARRAY* projections, ARRAY* splines, floatd3 phys_dims,ARRAY* exterior_path_lengths=NULL); 29 | 30 | 31 | template class ARRAY> void countProtonsPerVoxel(ARRAY* counts,ARRAY* splines, floatd3 phys_dims,ARRAY* exterior_path_lengths=NULL); 32 | 33 | template class ARRAY> void protonPathNorm(std::vector img_dims, ARRAY* projections, ARRAY* splines, floatd3 phys_dims,ARRAY* exterior_path_lengths=NULL ); 34 | 35 | template void pad_nearest( cuNDArray *in, cuNDArray *out ); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /proton/splineBackprojectionOperator.cu: -------------------------------------------------------------------------------- 1 | #include "splineBackprojectionOperator.h" 2 | #include "vector_td_utilities.h" 3 | #include "vector_td_io.h" 4 | #include "cuNDArray_math.h" 5 | #include "cuNDArray_reductions.h" 6 | #include "cuGaussianFilterOperator.h" 7 | #include "check_CUDA.h" 8 | 9 | #include 10 | 11 | #include 12 | #include "hoNDArray_fileio.h" 13 | #include "hoCuNDArray_math.h" 14 | 15 | 16 | #include "proton_utils.h" 17 | 18 | #define MAX_THREADS_PER_BLOCK 128 19 | #define BLOCKS_PER_GRID 65535 20 | #define MAX_BLOCKS 4096*4 21 | 22 | namespace Gadgetron{ 23 | 24 | 25 | 26 | template class ARRAY> void splineBackprojectionOperator 27 | ::mult_M( ARRAY* in_orig, ARRAY* out_orig, bool accumulate ) { 28 | if( !in_orig || !out_orig){ 29 | throw std::runtime_error( "cuOperatorPathBackprojection: mult_M empty data pointer"); 30 | } 31 | ARRAY* out = out_orig; 32 | if (accumulate) out = new ARRAY(out_orig->get_dimensions()); 33 | clear(out); 34 | 35 | ARRAY* in = in_orig; 36 | /* 37 | if (data->get_hull()){ 38 | in = new ARRAY(*in_orig); 39 | *in *= *data->get_hull(); 40 | } 41 | */ 42 | protonProjection(in,out,data->get_splines().get(),physical_dims,data->get_EPL().get()); 43 | 44 | if (data->get_weights() && use_weights){ 45 | *out *= *data->get_weights(); 46 | std::cout << "Using weights" << std::endl; 47 | } 48 | if (accumulate){ 49 | *out_orig += *out; 50 | delete out; 51 | } 52 | /* 53 | if (data->get_hull()) 54 | delete in; 55 | */ 56 | 57 | } 58 | 59 | template class ARRAY> void splineBackprojectionOperator 60 | ::mult_MH( ARRAY* in_orig, ARRAY* out_orig, bool accumulate ) { 61 | if( !in_orig || !out_orig){ 62 | throw std::runtime_error("cuOperatorPathBackprojection: mult_MH empty data pointer"); 63 | } 64 | ARRAY* out = out_orig; 65 | if (accumulate) out = new ARRAY(out_orig->get_dimensions()); 66 | 67 | clear(out); 68 | 69 | ARRAY* in = in_orig; 70 | if (data->get_weights() && use_weights){ 71 | in = new ARRAY(*in_orig); 72 | *in *= *data->get_weights(); 73 | } 74 | protonBackprojection(out,in,data->get_splines().get(),physical_dims,data->get_EPL().get()); 75 | //if (data->get_hull()) *out *= *data->get_hull(); 76 | if (accumulate){ 77 | *out_orig += *out; 78 | } 79 | if (accumulate) delete out; 80 | 81 | if (data->get_weights() && use_weights) delete in; 82 | } 83 | 84 | 85 | 86 | // Instantiations 87 | template class splineBackprojectionOperator; 88 | template class splineBackprojectionOperator; 89 | } 90 | -------------------------------------------------------------------------------- /proton/splineBackprojectionOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray_operators.h" 3 | #include "linearOperator.h" 4 | #include "cuNDArray.h" 5 | #include 6 | #include "GPUTimer.h" 7 | #include "protonDataset.h" 8 | 9 | #include "proton_utils.h" 10 | namespace Gadgetron{ 11 | template class ARRAY> 12 | class splineBackprojectionOperator : public linearOperator > { 13 | public: 14 | /** 15 | * Creates linearOperator for proton tomography, based on a dataset and a set of physical dimensions 16 | * @param data Proton data. Only splines are used internally. 17 | * @param physical_dims Physical dimensions of the image in cm 18 | */ 19 | splineBackprojectionOperator(boost::shared_ptr > data,floatd3 physical_dims) : linearOperator >() { 20 | this->physical_dims = physical_dims; 21 | this->data = data; 22 | linearOperator >::set_codomain_dimensions(data->get_projections()->get_dimensions().get()); 23 | use_weights = true; 24 | } 25 | virtual ~splineBackprojectionOperator() {} 26 | 27 | /** 28 | * Applies the operator ( = projection) 29 | * @param in 30 | * @param out 31 | * @param accumulate 32 | */ 33 | virtual void mult_M( ARRAY* in, ARRAY* out, bool accumulate = false ); 34 | /** 35 | * Applies the adjoint of the operator ( = backprojection) 36 | * @param in 37 | * @param out 38 | * @param accumulate 39 | */ 40 | virtual void mult_MH( ARRAY* in, ARRAY* out, bool accumulate = false ); 41 | 42 | 43 | 44 | virtual void set_codomain_dimensions( std::vector *dims ){ 45 | throw std::runtime_error("cuOperatorPathBackprojection::codomain dimension must be set through the setup function"); 46 | } 47 | virtual boost::shared_ptr< linearOperator< ARRAY > > clone() { 48 | return boost::shared_ptr< linearOperator< ARRAY > >(new splineBackprojectionOperator(data,physical_dims)); 49 | } 50 | 51 | 52 | virtual void pathNorm(ARRAY* projections){ 53 | protonPathNorm(*this->get_domain_dimensions(),projections,data->get_splines().get(),physical_dims,data->get_EPL().get()); 54 | } 55 | 56 | virtual void protonCount(ARRAY* count_img){ 57 | countProtonsPerVoxel(count_img,data->get_splines().get(),physical_dims,data->get_EPL().get()); 58 | } 59 | 60 | void set_use_weights(bool use){ use_weights = use;} 61 | 62 | protected: 63 | 64 | floatd3 physical_dims; 65 | boost::shared_ptr > data; 66 | bool use_weights; 67 | 68 | }; 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /python/cps2hdf5.py: -------------------------------------------------------------------------------- 1 | import hndreader 2 | import tables 3 | import glob 4 | from pylab import * 5 | import argparse 6 | from imshow2 import imshow2 7 | 8 | parser = argparse.ArgumentParser(description="Converts hnd files to hdf5 files") 9 | parser.add_argument("cps_file") 10 | parser.add_argument("--airscan",metavar="a",dest="airscan",help="Directory containing the airscan") 11 | args = parser.parse_args() 12 | 13 | # 14 | projs,heads = hndreader.readCps(args.cps_file) 15 | print "mAs",heads[0].xrayMA 16 | projs = array(projs,dtype=float32) 17 | # 18 | angles = [] 19 | offsetx = [] 20 | offsety = [] 21 | for head in heads: 22 | angles.append(head.ctProjectionAngle) 23 | offsetx.append(head.IDUPosLat) 24 | offsety.append(head.IDUPosLng) 25 | airfiles = [] 26 | if args.airscan: 27 | airfiles = glob.glob(args.airscan+"/*.hnd") 28 | airfiles.sort() 29 | 30 | airscan,_ = hndreader.readHnd(airfiles[0]) 31 | airscan = array(airscan,dtype=float32) 32 | for airfile in airfiles[1:]: 33 | airscanTmp,_ = hndreader.readHnd(airfile) 34 | airscan += airscanTmp 35 | airscan /= len(airfiles) 36 | if len(airfiles) > 0: 37 | projs /= airscan 38 | else: 39 | projs /= amax(projs) 40 | 41 | projs = -log(projs) 42 | print "Projs contains NaN:",any(isnan(projs)),"Infs:",any(isinf(projs)) 43 | projs[isinf(projs)] = 0 44 | outfile = "projections.hdf5" 45 | 46 | head = heads[0] 47 | #projections /= amax(projections) 48 | #projections = -log(projections) 49 | f = tables.openFile(outfile,"w") 50 | root = f.getNode("/") 51 | f.createArray(root,"SAD",array([head.SAD*10],dtype=float32)) 52 | f.createArray(root,"SDD",array([(head.SAD-head.IDUPosVrt)*10],dtype=float32)) 53 | f.createArray(root,"angles",array(angles,dtype=float32)) 54 | f.createArray(root,"geometry_dataformat_version",array([2],dtype=int32)) 55 | f.createArray(root,"offsetx",array(offsetx,dtype=float32)) 56 | f.createArray(root,"offsety",array(offsety,dtype=float32)) 57 | # 58 | f.createArray(root,"projection_dataformat_version",array([1],dtype=int32)) 59 | 60 | f.createArray(root,"projections",projs) 61 | f.createArray(root,"spacing",array([head.IDUResolutionX,head.IDUResolutionY],dtype=float32)) 62 | -------------------------------------------------------------------------------- /python/hndreader.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import struct 3 | from collections import namedtuple 4 | import pyximport; pyximport.install() 5 | import hndImageReader 6 | 7 | def readHnd(filename): 8 | totbytes = 120+10*4+41*8 9 | HndHeader = namedtuple("HndHeader","filetype filelength checksumSpec checksum creationDate creationTime patientID patientSer seriesID seriesSer "\ 10 | "sliceID sliceSer sizeX sizeY sliceZPos modality window level pixelOffset imageType gantryRotation SAD SFD collX1 collX2 collY1 collY2 "\ 11 | "collRotation filedX filedY bladeX1 bladeX2 bladeY1 bladeY2 IDUPosLng IDUPosLat IDUPosVrt IDUPosRtn patientSupportAngle tableTopEccentricAngle "\ 12 | "couchVrt couchLng couchLat IDUResolutionX IDUResolutionY imageResolutionX imageResolutionY energy doseRate xRayKV xrayMA metersetExposure " \ 13 | "acqAdjustment ctProjectionAngle ctNormChamber gatingTimeTag gating4DInfoX gating4DInfoY gating4DInfoZ gating4DInfoTime") 14 | with open(filename,"rb") as f: 15 | data = f.read(totbytes) 16 | formatstring = "=32sI4sI8s8s16sI16sI16sIIId16sIII4sdddddddddddddddddddddddddddddddddddddddd" 17 | header = HndHeader._make(struct.unpack(formatstring,data)) 18 | image = hndImageReader.readHndImage(filename,[header.sizeX,header.sizeY]) 19 | 20 | return image,header 21 | 22 | def readCps(filename): 23 | results = hndImageReader.readCpsImage(filename) 24 | 25 | return results 26 | -------------------------------------------------------------------------------- /python/readReal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri Sep 23 11:31:46 2011 4 | 5 | @author: Dae 6 | """ 7 | from __future__ import print_function 8 | import numpy as np 9 | 10 | class RealFile: 11 | def __init__(self,filename,dims,dtype=np.float32): 12 | self.ft = open(filename,'wb') 13 | self.dims = dims 14 | np.array(len(dims),dtype=np.uint32).tofile(self.ft) 15 | self.dtype = dtype 16 | self.closed = False 17 | self.elemsAdded = 0 18 | for i in range(len(dims)): 19 | np.array(dims[i],dtype=np.uint32).tofile(self.ft) 20 | 21 | def append(self,a): 22 | np.array(a,dtype=self.dtype).tofile(self.ft) 23 | self.elemsAdded += np.prod(a.shape) 24 | def close(self): 25 | if (self.elemsAdded != np.prod(self.dims)): 26 | print( 'Warning, number of elements in shape ', np.prod(self.dims), ' does not match number of elements added ',self.elemsAdded) 27 | self.close = True 28 | 29 | self.ft.close() 30 | def header(self,dims): 31 | if len(dims) != len(self.dims): 32 | print( 'Warning: New dimensions has different length than old dimension. Aborting!') 33 | return 34 | self.dims = dims 35 | self.ft.seek(0) 36 | np.array(len(dims),dtype=np.uint32).tofile(self.ft) 37 | for i in range(len(dims)): 38 | np.array(dims[i],dtype=np.uint32).tofile(self.ft) 39 | self.ft.seek(0,2) 40 | 41 | def readReal(f): 42 | if( type(f) == type('s')): 43 | ft = open(f,'rb') 44 | else: 45 | ft = f 46 | 47 | dims = np.fromfile(ft,dtype=np.uint32,count=1) 48 | print("dims",dims) 49 | shape= np.fromfile(ft,dtype=np.uint32,count=dims[0]) 50 | curPos = ft.tell() 51 | ft.seek(0,2) 52 | size = ft.tell()-curPos 53 | ft.seek(curPos) 54 | 55 | if (size > np.prod(shape)*4): 56 | array = np.fromfile(ft,dtype=np.complex64) 57 | else: 58 | array = np.fromfile(ft,dtype=np.float32) 59 | array = array.reshape(shape[::-1]) 60 | if( type(f) == 'str'): 61 | ft.close() 62 | 63 | return array 64 | def saveReal(a,f,dtype=np.float32): 65 | if( type(f) == type('s')): 66 | ft = open(f,'wb') 67 | else: 68 | ft = f 69 | s = a.shape 70 | np.array(len(s),dtype=np.uint32).tofile(ft) 71 | s = s[::-1] 72 | for i in range(len(s)): 73 | np.array(s[i],dtype=np.uint32).tofile(ft) 74 | np.array(a,dtype=dtype).tofile(ft) 75 | if( type(f) == 'str'): 76 | ft.close() 77 | -------------------------------------------------------------------------------- /python/varian_utils.py: -------------------------------------------------------------------------------- 1 | 2 | import xml.etree.ElementTree as ET 3 | import collections 4 | import numpy as np 5 | from scipy.signal import fftconvolve 6 | from scipy.ndimage.interpolation import zoom 7 | import pylab 8 | def parse_scatter(scatter_file): 9 | ns = {'varian': 'http://baden.varian.com/cr.xsd'} 10 | scatter = collections.namedtuple("ScatterModel", "Thickness A alpha beta sigma1 B sigma2 gamma MagFactor") 11 | tree = ET.parse(scatter_file) 12 | 13 | root = tree.getroot() 14 | 15 | scatter_models = root.find("varian:CalibrationResults",ns).find("varian:ObjectScatterModels",ns) 16 | 17 | scatterers = [] 18 | for scatter_model in scatter_models.findall("varian:ObjectScatterModel",ns): 19 | 20 | thickness = float(scatter_model.find('varian:Thickness',ns).text) 21 | OSF = scatter_model.find("varian:ObjectScatterFit",ns) 22 | 23 | A = float(OSF.find('varian:A', ns).text) 24 | B = float(OSF.find('varian:B', ns).text) 25 | alpha = float(OSF.find('varian:alpha', ns).text) 26 | beta = float(OSF.find('varian:beta', ns).text) 27 | sigma1 = float(OSF.find('varian:sigma1', ns).text) 28 | sigma2 = float(OSF.find('varian:sigma2', ns).text) 29 | gamma = float(OSF.find('varian:gamma', ns).text) 30 | MagFactor = float(OSF.find('varian:MagFactor', ns).text) 31 | 32 | 33 | scatterers.append(scatter(thickness,A,alpha,beta,sigma1,B,sigma2,gamma,MagFactor)) 34 | 35 | return scatterers 36 | 37 | 38 | def calculate_scatter(scatterModel,I0,IP,thickness,mask): 39 | logI0IP = np.log(I0 / IP) 40 | logI0IP[logI0IP < 0] = 0 41 | amplitude_factor = scatterModel.A*(IP/I0)**scatterModel.alpha*logI0IP**scatterModel.beta*mask 42 | 43 | 44 | s= np.shape(I0) 45 | xx,yy = np.mgrid[:s[0],:s[1]] 46 | xx -= s[0]/2 47 | yy -= s[1]/2 48 | 49 | g = np.exp(-(xx**2+yy**2)/(2*scatterModel.sigma1**2))+scatterModel.B*np.exp(-(xx**2+yy**2)/(2*scatterModel.sigma2**2)) 50 | 51 | scatter = (1-scatterModel.gamma*thickness)*fftconvolve(amplitude_factor*IP,g,mode="same")+\ 52 | scatterModel.gamma*fftconvolve(amplitude_factor*thickness*IP,g,mode="same") 53 | 54 | 55 | return scatter 56 | 57 | 58 | 59 | 60 | def adaptive_correct_scatter(scatterModels,I0,IP,pixelsize): 61 | 62 | s = np.shape(I0) 63 | 64 | new_pixelsize = (4.0,4.0) 65 | new_imagesize = (10.0,26.0) 66 | print s,new_imagesize 67 | I0_small = zoom(I0,new_imagesize) 68 | IP_small = zoom(IP, new_imagesize) 69 | 70 | scatter_old = np.zeros_like(I0_small) 71 | 72 | mu = 0.02 73 | step_size = 0.6 74 | t = np.log(I0_small/IP_small)/mu 75 | 76 | pylab.imshow(t,cmap="viridis") 77 | pylab.show() 78 | 79 | for k in range(1): 80 | total_scatter = np.zeros_like(I0_small) 81 | 82 | for i in range(len(scatterModels)-1): 83 | thickness1 = scatterModels[i].Thickness 84 | thickness2 = scatterModels[i+1].Thickness 85 | mask = np.logical_and(t > thickness1, t < thickness2) 86 | total_scatter += calculate_scatter(scatterModels[i],I0_small,IP_small,t,mask) 87 | 88 | total_scatter += calculate_scatter(scatterModels[i],I0_small,IP_small,t,t > scatterModels[-1].Thickness) 89 | 90 | 91 | IP_small += step_size*(scatter_old-total_scatter) 92 | scatter_old = total_scatter 93 | 94 | s2 = np.shape(I0_small) 95 | scatter = zoom(scatter_old,(float(s[0])/s2[0],float(s[1])/s2[1])) 96 | 97 | SF = np.minimum(scatter/IP,0.95) 98 | print "SF",np.shape(SF),np.shape(scatter) 99 | result = IP*(1.0-SF) 100 | 101 | pylab.imshow(IP, cmap="viridis") 102 | pylab.figure() 103 | pylab.imshow(scatter, cmap="viridis") 104 | pylab.figure() 105 | pylab.imshow(SF, cmap="viridis") 106 | pylab.figure() 107 | pylab.imshow(result,cmap="viridis") 108 | pylab.show() 109 | return result 110 | 111 | -------------------------------------------------------------------------------- /registration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories( 3 | ${CUDA_INCLUDE_DIRS} 4 | ${Boost_INCLUDE_DIR} 5 | ${GADGETRON_INCLUDE_DIR} 6 | ${GDCM_INCLUDE_DIRS} 7 | ${CMAKE_SOURCE_DIR}/solvers 8 | ${CMAKE_SOURCE_DIR}/operators 9 | ${CMAKE_SOURCE_DIR}/proton 10 | ) 11 | 12 | 13 | cuda_add_library(gt_registration SHARED 14 | cuDemonsSolver.cu 15 | quadratureKernels.cpp 16 | morphon.cu 17 | ) 18 | 19 | 20 | 21 | add_executable(register_Demons_3dV2 register_Demons_3dV2.cpp) 22 | target_link_libraries(register_Demons_3dV2 gt_registration tomography_solvers gadgetron_toolbox_cpureg gadgetron_toolbox_gpureg gadgetron_toolbox_log tomography_operators gadgetron_toolbox_gpusolvers gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_gpucore gadgetron_toolbox_cpureg gadgetron_toolbox_gpuoperators gadgetron_toolbox_hostutils gadgetron_toolbox_gpureg ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 23 | 24 | add_executable(register_Demons_3d register_Demons_3d.cpp) 25 | target_link_libraries(register_Demons_3d gt_registration tomography_solvers gadgetron_toolbox_cpureg gadgetron_toolbox_gpureg gadgetron_toolbox_log tomography_operators gadgetron_toolbox_gpusolvers gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_gpucore gadgetron_toolbox_cpureg gadgetron_toolbox_gpuoperators gadgetron_toolbox_hostutils gadgetron_toolbox_gpureg ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 26 | 27 | add_executable(register_Demons_4d register_Demons_4d.cpp) 28 | target_link_libraries(register_Demons_4d gt_registration tomography_solvers gadgetron_toolbox_cpureg gadgetron_toolbox_gpureg gadgetron_toolbox_log tomography_operators gadgetron_toolbox_gpusolvers gadgetron_toolbox_cpucore gadgetron_toolbox_cpucore_math gadgetron_toolbox_gpucore gadgetron_toolbox_cpureg gadgetron_toolbox_gpuoperators gadgetron_toolbox_hostutils gadgetron_toolbox_gpureg ${HDF5_LIBRARIES} ${CUDA_CUFFT_LIBRARIES} ${CULA_LIBRARIES} ${CUDA_LIBRARIES} ${Boost_LIBRARIES}) 29 | 30 | install(TARGETS register_Demons_3dV2 DESTINATION bin COMPONENT main) 31 | install(TARGETS register_Demons_3d DESTINATION bin COMPONENT main) 32 | install(TARGETS register_Demons_4d DESTINATION bin COMPONENT main) 33 | install(TARGETS gt_registration 34 | LIBRARY DESTINATION lib 35 | ARCHIVE DESTINATION lib 36 | RUNTIME DESTINATION bin 37 | COMPONENT main 38 | ) 39 | -------------------------------------------------------------------------------- /registration/Matrix.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dchansen on 11/7/19. 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | template< class T, unsigned int M, unsigned int N> 10 | struct Matrix{ 11 | 12 | Gadgetron::vector_td data[M]; 13 | 14 | __host__ __device__ T& operator()(int m, int n){ 15 | return data[m][n]; 16 | } 17 | 18 | __host__ __device__ T operator()(int m, int n) const { 19 | return data[m][n]; 20 | } 21 | 22 | }; 23 | 24 | 25 | template 26 | __host__ __device__ Gadgetron::vector_td dot(const Matrix& matrix, const Gadgetron::vector_td& vec){ 27 | using namespace Gadgetron; 28 | vector_td result; 29 | for (int i = 0; i < M; i++) 30 | result[i] = dot(matrix.data[i],vec); 31 | 32 | return result; 33 | } 34 | -------------------------------------------------------------------------------- /registration/cuDemonsSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cuNDArray_math.h" 3 | #include "cuNDArray_utils.h" 4 | #include "multiresRegistrationSolver.h" 5 | #include "cuGaussianFilterOperator.h" 6 | #include "vector_td.h" 7 | #include "cuNDArray.h" 8 | 9 | namespace Gadgetron{ 10 | 11 | cuNDArray deform_image(const cuNDArray& image, const cuNDArray& vector_field); 12 | cuNDArray deform_image(cudaTextureObject_t texObj, const std::vector& dimensions, cuNDArray& vector_field); 13 | void deform_vfield(cuNDArray& vfield1, const cuNDArray& vector_field); 14 | 15 | void bilateral_vfield(cuNDArray& vfield1, cuNDArray& image, floatd3 sigma_spatial,float sigma_int, float sigma_diff); 16 | cuNDArray Jacobian(cuNDArray* vfield); 17 | 18 | 19 | template class cuDemonsSolver { 20 | 21 | 22 | public: 23 | cuDemonsSolver() : alpha(1.0),beta(1e-6),sigmaDiff(1.0),sigmaFluid(1.0),compositive(false),epsilonNGF(0),exponential(false) {}; 24 | virtual ~cuDemonsSolver(){}; 25 | 26 | cuNDArray registration( const cuNDArray &fixed_image, const cuNDArray &moving_image); 27 | cuNDArray multi_level_reg( const cuNDArray &fixed_image, const cuNDArray &moving_image,int levels, float scale = 1.0f); 28 | 29 | void set_iterations(int i){ 30 | iterations = i; 31 | } 32 | void set_sigmaDiff(T _sigma){ 33 | sigmaDiff = vector_td(_sigma); 34 | 35 | } 36 | void set_sigmaDiff(vector_td _sigma){ 37 | sigmaDiff = _sigma; 38 | 39 | } 40 | 41 | void set_sigmaFluid(T _sigma){ 42 | sigmaFluid = _sigma; 43 | 44 | } 45 | void set_alpha(T _alpha){ 46 | alpha = _alpha; 47 | } 48 | 49 | void set_compositive(bool option){ 50 | compositive = option; 51 | } 52 | 53 | void set_exponential(bool option){ 54 | exponential = option; 55 | } 56 | 57 | void use_normalized_gradient_field(T epsilon){ 58 | epsilonNGF = epsilon; 59 | } 60 | 61 | 62 | void set_sigmaVDiff(T sigma){ 63 | sigmaVDiff = sigma; 64 | } 65 | 66 | void set_sigmaInt(T sigma){ 67 | sigmaInt = sigma; 68 | } 69 | 70 | 71 | 72 | protected: 73 | cuNDArray demonicStep(const cuNDArray&, const cuNDArray&); 74 | void single_level_reg( const cuNDArray &fixed_image, const cuNDArray& moving_image,cuNDArray& result, float scale=1.0f); 75 | 76 | 77 | 78 | void upscale_vfield(const cuNDArray& in,cuNDArray& out); 79 | T sigmaFluid,sigmaInt,sigmaVDiff,alpha,beta,epsilonNGF; 80 | vector_td sigmaDiff; 81 | bool compositive, exponential; 82 | int iterations; 83 | }; 84 | 85 | 86 | } 87 | -------------------------------------------------------------------------------- /registration/morphon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cuNDArray.h" 4 | 5 | boost::shared_ptr> morphon(Gadgetron::cuNDArray* moving, Gadgetron::cuNDArray* fixed); -------------------------------------------------------------------------------- /registration/quadratureKernels.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "vector_td.h" 5 | 6 | class quadratureKernels { 7 | public: 8 | static std::vector> kernels; 9 | //static std::vector m11, m12, m13, m22, m23, m33; 10 | static std::vector> Tensor; 11 | static std::vector directions; 12 | 13 | }; 14 | 15 | -------------------------------------------------------------------------------- /solvers/ADMM.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray_math.h" 4 | #include "cuNDArray_math.h" 5 | namespace Gadgetron{ 6 | template class ADMM{ 7 | 8 | public: 9 | ADMM(SOLVER* solver): solver_(solver){ 10 | 11 | } 12 | 13 | boost::shared_ptr solve(ARRAY* input){ 14 | boost::shared_ptr x; 15 | 16 | float mu = mean(weights_.get()); 17 | 18 | std::vector dims = *solver_->get_encoding_operator()->get_domain_dimensions(); 19 | ARRAY u(*input); 20 | 21 | ARRAY Wy(*input); 22 | ARRAY nabla(input->get_dimensions()); 23 | clear(&nabla); 24 | Wy *= *weights_; 25 | 26 | ARRAY D(*weights_); 27 | D += mu; 28 | 29 | 30 | for (int i = 0; i < iterations; i++ ){ 31 | ARRAY tmp(u); 32 | tmp -= nabla; 33 | x = solver_->solve(&tmp); 34 | solver_->get_encoding_operator()->mult_M(x.get(),&tmp); 35 | u = tmp; 36 | u += nabla; 37 | u *= mu; 38 | u += Wy; 39 | u /= D; 40 | 41 | tmp -= u; 42 | 43 | std::cout << "Iteration " << i << " Res: " << nrm2(&tmp) << std::endl; 44 | nabla += tmp; 45 | 46 | 47 | 48 | 49 | } 50 | return x; 51 | 52 | 53 | 54 | } 55 | 56 | 57 | SOLVER* get_solver(){ 58 | return solver_; 59 | } 60 | 61 | void set_weights(boost::shared_ptr weights){weights_ = weights;} 62 | void set_iterations(int it ){ iterations = it;} 63 | SOLVER* solver_; 64 | boost::shared_ptr weights_; 65 | int iterations; 66 | }; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /solvers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (WIN32) 2 | ADD_DEFINITIONS(-D__BUILD_GADGETRON_SOLVERS__) 3 | endif (WIN32) 4 | include_directories( 5 | ${CUDA_INCLUDE_DIRS} 6 | ${Boost_INCLUDE_DIR} 7 | ${GADGETRON_INCLUDE_DIR} 8 | ${GDCM_INCLUDE_DIRS} 9 | ${CMAKE_SOURCE_DIR}/operators 10 | ${CMAKE_SOURCE_DIR}/proton 11 | ${CMAKE_SOURCE_DIR}/denoise 12 | ) 13 | 14 | 15 | cuda_add_library( tomography_solvers SHARED 16 | solver_utils.cu solver_utils.h cuOSMOMSolverD.cu 17 | 18 | ) 19 | 20 | target_link_libraries(tomography_solvers gadgetron_toolbox_gpusolvers) 21 | install(FILES 22 | cuNCGSolver.h 23 | mlSolver.h 24 | cuMLSolver.h 25 | cuSARTSolver.h 26 | sartSolver.h 27 | hoGPBBSolver.h 28 | DESTINATION include) 29 | install(TARGETS tomography_solvers 30 | LIBRARY DESTINATION lib 31 | ARCHIVE DESTINATION lib 32 | RUNTIME DESTINATION bin 33 | COMPONENT main 34 | ) 35 | -------------------------------------------------------------------------------- /solvers/cuMLSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mlSolver.h" 4 | 5 | namespace Gadgetron{ 6 | template class cuMLSolver : public mlSolver >{ 7 | public: 8 | cuMLSolver() : mlSolver >() {} 9 | virtual ~cuMLSolver(){}; 10 | 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /solvers/cuNCGSolver.cu: -------------------------------------------------------------------------------- 1 | #include "cuNCGSolver.h" 2 | #include "complext.h" 3 | 4 | #define MAX_THREADS_PER_BLOCK 512 5 | 6 | using namespace Gadgetron; 7 | template __global__ static void filter_kernel(T* x, T* g, int elements){ 8 | const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; 9 | if (idx < elements){ 10 | if ( x[idx] <= T(0) && g[idx] > 0) g[idx]=T(0); 11 | } 12 | } 13 | 14 | template __global__ static void filter_kernel(complext* x, complext* g, int elements){ 15 | const int idx = blockIdx.y*gridDim.x*blockDim.x + blockIdx.x*blockDim.x + threadIdx.x; 16 | if (idx < elements){ 17 | if ( real(x[idx]) <= REAL(0) && real(g[idx]) > 0) g[idx].vec[0] = REAL(0); 18 | g[idx].vec[1]=REAL(0); 19 | } 20 | } 21 | 22 | template void Gadgetron::cuNCGSolver:: 23 | solver_non_negativity_filter(Gadgetron::cuNDArray* x , Gadgetron::cuNDArray* g) 24 | { 25 | int elements = g->get_number_of_elements(); 26 | 27 | int threadsPerBlock = std::min(elements,MAX_THREADS_PER_BLOCK); 28 | dim3 dimBlock( threadsPerBlock); 29 | int totalBlocksPerGrid = std::max(1,elements/MAX_THREADS_PER_BLOCK); 30 | dim3 dimGrid(totalBlocksPerGrid); 31 | 32 | filter_kernel::Type><<>>(x->get_data_ptr(),g->get_data_ptr(),elements); 33 | } 34 | 35 | 36 | template class EXPORTGPUSOLVERS Gadgetron::cuNCGSolver; 37 | template class EXPORTGPUSOLVERS Gadgetron::cuNCGSolver; 38 | 39 | template class EXPORTGPUSOLVERS Gadgetron::cuNCGSolver< complext >; 40 | template class EXPORTGPUSOLVERS Gadgetron::cuNCGSolver< complext >; 41 | -------------------------------------------------------------------------------- /solvers/cuNCGSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "solver_utils.h" 4 | #include "ncgSolver.h" 5 | #include "cuNDArray_operators.h" 6 | #include "cuNDArray_elemwise.h" 7 | #include "cuNDArray_blas.h" 8 | #include "real_utilities.h" 9 | #include "vector_td_utilities.h" 10 | #include "gpusolvers_export.h" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | #include "hoNDArray_fileio.h" 19 | namespace Gadgetron{ 20 | 21 | template class EXPORTGPUSOLVERS cuNCGSolver : public ncgSolver > 22 | { 23 | public: 24 | 25 | cuNCGSolver() : ncgSolver >() {} 26 | virtual ~cuNCGSolver() {} 27 | 28 | 29 | /* 30 | virtual void iteration_callback(cuNDArray* x ,int iteration,typename realType::Type value){ 31 | if (iteration == 0){ 32 | std::ofstream textFile("residual.txt",std::ios::trunc); 33 | textFile << value << std::endl; 34 | } else{ 35 | std::ofstream textFile("residual.txt",std::ios::app); 36 | textFile << value << std::endl; 37 | } 38 | 39 | std::stringstream ss; 40 | ss << "NCG-" << iteration << ".real"; 41 | write_nd_array(x->to_host().get(),ss.str().c_str()); 42 | 43 | 44 | }; 45 | */ 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /solvers/cuOSMOMSolverD.cu: -------------------------------------------------------------------------------- 1 | #include "cuOSMOMSolverD.h" 2 | #include 3 | #include 4 | 5 | using namespace Gadgetron; 6 | 7 | 8 | template struct updateG_functor { 9 | 10 | typedef typename realType::Type REAL; 11 | updateG_functor(REAL tau_, REAL avg_lambda_) : tau(tau_), avg_lambda(avg_lambda_){ 12 | } 13 | 14 | __device__ __inline__ T operator() (thrust::tuple tup){ 15 | T g = thrust::get<0>(tup); 16 | T x = thrust::get<1>(tup); 17 | T s = thrust::get<2>(tup); 18 | T precon = thrust::get<3>(tup); 19 | 20 | T result = (x-tau*g)+tau/avg_lambda*s/precon; 21 | result /= precon*tau/avg_lambda+REAL(1); 22 | return result; 23 | 24 | 25 | } 26 | 27 | typename realType::Type tau,avg_lambda; 28 | }; 29 | 30 | template void cuOSMOMSolverD::updateG(cuNDArray& g, cuNDArray& x,cuNDArray& s, cuNDArray& precon, REAL tau, REAL avg_lambda ){ 31 | auto begin_iterator = thrust::make_zip_iterator(thrust::make_tuple(g.begin(),x.begin(),s.begin(),precon.begin())); 32 | auto end_iterator = thrust::make_zip_iterator(thrust::make_tuple(g.end(),x.end(),s.end(),precon.end())); 33 | thrust::transform(begin_iterator,end_iterator,x.begin(),updateG_functor(tau,avg_lambda)); 34 | } 35 | 36 | template class cuOSMOMSolverD; 37 | -------------------------------------------------------------------------------- /solvers/cuOSMOMSolverD.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "cuSolverUtils.h" 6 | #include "osMOMSolverD.h" 7 | namespace Gadgetron { 8 | template 9 | class cuOSMOMSolverD : public osMOMSolverD> { 10 | typedef typename realType::Type REAL; 11 | virtual void updateG(cuNDArray& g, cuNDArray& x,cuNDArray& s, cuNDArray& precon, REAL tau, REAL avg_lambda ) override; 12 | }; 13 | } -------------------------------------------------------------------------------- /solvers/cuSARTSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "sartSolver.h" 4 | 5 | namespace Gadgetron{ 6 | template class cuSARTSolver : public sartSolver >{ 7 | public: 8 | cuSARTSolver() : sartSolver >() {} 9 | virtual ~cuSARTSolver(){}; 10 | 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /solvers/hoABIBBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ABIBBSolver.h" 4 | #include "hoNDArray_fileio.h" 5 | #include 6 | 7 | namespace Gadgetron{ 8 | 9 | template class hoABIBBSolver : public ABIBBSolver{ 10 | 11 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 12 | typedef typename realType::Type REAL; 13 | public: 14 | virtual ~hoABIBBSolver(){}; 15 | protected: 16 | virtual void solver_non_negativity_filter(ARRAY_TYPE *xdata,ARRAY_TYPE *gdata){ 17 | ELEMENT_TYPE* x = xdata->get_data_ptr(); 18 | ELEMENT_TYPE* g = gdata->get_data_ptr(); 19 | for (int i = 0; i != xdata->get_number_of_elements(); ++i) 20 | if ( real(x[i]) <= REAL(0) && real(g[i]) > 0) g[i]=ELEMENT_TYPE(0); 21 | } 22 | 23 | virtual void iteration_callback(ARRAY_TYPE* x, int i){ 24 | std::stringstream ss; 25 | ss << "iteration-" << i << ".real"; 26 | write_nd_array(x,ss.str().c_str()); 27 | } 28 | }; 29 | /** 30 | * Specialization to disable class for cuNDArrays 31 | */ 32 | template class hoABIBBSolver > { 33 | virtual void hoABIBBSolver_only_works_for_host_arrays() =0; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /solvers/hoCuBILBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "BILBSolver.h" 4 | //#include "hoNDArray_fileio.h" 5 | //#include 6 | 7 | namespace Gadgetron{ 8 | 9 | template class hoCuBILBSolver : public BILBSolver{ 10 | 11 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 12 | typedef typename realType::Type REAL; 13 | public: 14 | virtual ~hoCuBILBSolver(){}; 15 | protected: 16 | virtual void solver_non_negativity_filter(ARRAY_TYPE *xdata,ARRAY_TYPE *gdata){ 17 | ELEMENT_TYPE* x = xdata->get_data_ptr(); 18 | ELEMENT_TYPE* g = gdata->get_data_ptr(); 19 | for (int i = 0; i != xdata->get_number_of_elements(); ++i) 20 | if ( real(x[i]) <= REAL(0) && real(g[i]) > 0) g[i]=ELEMENT_TYPE(0); 21 | } 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /solvers/hoCuCgDescentSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cgdescentSolver.h" 4 | #include "hoNDArray_math.h" 5 | #include "hoCuNDArray_blas.h" 6 | #include "hoNDArray_fileio.h" 7 | #include "complext.h" 8 | 9 | namespace Gadgetron{ 10 | 11 | template class hoCuCgDescentSolver: public cgdescentSolver >{ 12 | typedef typename realType::Type REAL; 13 | public: 14 | hoCuCgDescentSolver():cgdescentSolver >(){ 15 | 16 | } 17 | 18 | virtual ~hoCuCgDescentSolver(){}; 19 | 20 | protected: 21 | virtual void solver_non_negativity_filter(hoCuNDArray *x,hoCuNDArray *g) 22 | { 23 | T* x_ptr = x->get_data_ptr(); 24 | T* g_ptr = g->get_data_ptr(); 25 | for (int i =0; i < x->get_number_of_elements(); i++){ 26 | if ( real(x_ptr[i]) <= REAL(0) && real(g_ptr[i]) > 0) g_ptr[i]=T(0); 27 | } 28 | 29 | } 30 | 31 | virtual void iteration_callback(hoCuNDArray* x,int i,REAL data_res,REAL reg_res){ 32 | /* 33 | if (i == 0){ 34 | std::ofstream textFile("residual.txt",std::ios::trunc); 35 | textFile << data_res << std::endl; 36 | } else{ 37 | std::ofstream textFile("residual.txt",std::ios::app); 38 | textFile << data_res << std::endl; 39 | } 40 | std::stringstream ss; 41 | ss << "iteration-" << i << ".real"; 42 | write_nd_array(x,ss.str().c_str());*/ 43 | }; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /solvers/hoCuCgSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cgSolver.h" 4 | 5 | #include "cgSolver.h" 6 | #include "hoNDArray_operators.h" 7 | #include "hoNDArray_elemwise.h" 8 | #include "hoCuNDArray_blas.h" 9 | 10 | namespace Gadgetron{ 11 | 12 | /** \class hoCuCgSolver 13 | \brief Instantiation of the conjugate gradient solver on the cpu. 14 | 15 | The class hoCuCgSolver is a convienience wrapper for the device independent cgSolver class. 16 | hoCuCgSolver instantiates the cgSolver for type hoNDArray. 17 | */ 18 | template class hoCuCgSolver : public cgSolver< hoCuNDArray > 19 | { 20 | public: 21 | hoCuCgSolver() : cgSolver >(), _it(0) {} 22 | virtual ~hoCuCgSolver() {} 23 | 24 | /* TSS: This is too expensive to do in general. Move responsibility of dumping to the apps. 25 | virtual void solver_dump(hoCuNDArray* x){ 26 | std::stringstream ss; 27 | ss << "iteration-" << _it << ".real"; 28 | write_nd_array(x,ss.str().c_str()); 29 | _it++; 30 | }*/ 31 | 32 | private: 33 | int _it; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /solvers/hoCuGPBBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gpBbSolver.h" 4 | #include "hoNDArray_elemwise.h" 5 | #include "hoCuNDArray_blas.h" 6 | #include "complext.h" 7 | 8 | namespace Gadgetron{ 9 | 10 | template class hoCuGPBBSolver: public gpBbSolver >{ 11 | typedef typename realType::Type REAL; 12 | public: 13 | hoCuGPBBSolver():gpBbSolver >(){ 14 | 15 | } 16 | 17 | virtual ~hoCuGPBBSolver(){}; 18 | 19 | protected: 20 | virtual void solver_non_negativity_filter(hoCuNDArray *x,hoCuNDArray *g) 21 | { 22 | T* x_ptr = x->get_data_ptr(); 23 | T* g_ptr = g->get_data_ptr(); 24 | for (int i =0; i < x->get_number_of_elements(); i++){ 25 | if ( real(x_ptr[i]) < REAL(0) && real(g_ptr[i]) > 0) g_ptr[i]=T(0); 26 | } 27 | 28 | } 29 | 30 | virtual void solver_reciprocal_clamp( hoCuNDArray* x_arr, REAL threshold){ 31 | T* x = x_arr->get_data_ptr(); 32 | for (int i = 0; i < x_arr->get_number_of_elements(); i++){ 33 | if (real(x[i]) < threshold) x[i]= T(0); 34 | else x[i]= T(1)/x[i]; 35 | } 36 | } 37 | 38 | virtual void iteration_callback(hoCuNDArray*,int i,REAL,REAL){ 39 | //std::cout << "Free memory: " << cudaDeviceManager::Instance()->getFreeMemory() << std::endl; 40 | }; 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /solvers/hoCuNCGSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray_math.h" 4 | #include "hoCuNDArray_blas.h" 5 | #include "hoNDArray_fileio.h" 6 | #include "complext.h" 7 | #include "ncgSolver.h" 8 | 9 | namespace Gadgetron{ 10 | 11 | template class hoCuNCGSolver: public ncgSolver >{ 12 | typedef typename realType::Type REAL; 13 | public: 14 | hoCuNCGSolver():ncgSolver >(){ 15 | 16 | } 17 | 18 | virtual ~hoCuNCGSolver(){}; 19 | 20 | protected: 21 | virtual void solver_non_negativity_filter(hoCuNDArray *x,hoCuNDArray *g) 22 | { 23 | T* x_ptr = x->get_data_ptr(); 24 | T* g_ptr = g->get_data_ptr(); 25 | for (int i =0; i < x->get_number_of_elements(); i++){ 26 | if ( real(x_ptr[i]) <= REAL(0) && real(g_ptr[i]) > 0) g_ptr[i]=T(0); 27 | } 28 | 29 | } 30 | 31 | virtual void iteration_callback(hoCuNDArray* x,int i,REAL data_res,REAL reg_res){ 32 | 33 | if (i == 0){ 34 | std::ofstream textFile("residual.txt",std::ios::trunc); 35 | textFile << data_res << std::endl; 36 | } else{ 37 | std::ofstream textFile("residual.txt",std::ios::app); 38 | textFile << data_res << std::endl; 39 | } 40 | /*std::stringstream ss; 41 | ss << "iteration-" << i << ".real"; 42 | write_nd_array(x,ss.str().c_str());*/ 43 | }; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /solvers/hoCuSbcCgSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoCuCgSolver.h" 4 | #include "sbcSolver.h" 5 | 6 | #include "complext.h" 7 | 8 | namespace Gadgetron{ 9 | 10 | template class hoCuSbcCgSolver : public sbcSolver< hoCuNDArray::Type >, hoCuNDArray, hoCuCgSolver > 11 | { 12 | public: 13 | hoCuSbcCgSolver() : sbcSolver::Type >, hoCuNDArray, hoCuCgSolver >(),_it(0) {} 14 | virtual ~hoCuSbcCgSolver() {} 15 | /* 16 | virtual bool post_linear_solver_callback( hoCuNDArray* x) { 17 | 18 | std::stringstream ss; 19 | ss << "iteration-" << _it << ".real"; 20 | write_nd_array(x,ss.str().c_str()); 21 | _it++; 22 | return true; 23 | 24 | } 25 | */ 26 | private: 27 | int _it; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /solvers/hoCuSolverUtils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * hoCuSolverUtils.h 3 | * 4 | * Created on: Nov 11, 2015 5 | * Author: dch 6 | */ 7 | 8 | #ifndef HOCUSOLVERUTILS_H_ 9 | #define HOCUSOLVERUTILS_H_ 10 | 11 | 12 | 13 | 14 | 15 | #endif /* HOCUSOLVERUTILS_H_ */ 16 | -------------------------------------------------------------------------------- /solvers/hoCuTTSSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ttsSolver.h" 4 | #include "hoNDArray_math.h" 5 | #include "hoCuNDArray_blas.h" 6 | #include "hoNDArray_fileio.h" 7 | #include "complext.h" 8 | 9 | namespace Gadgetron{ 10 | 11 | template class hoCuTTSSolver: public ttsSolver >{ 12 | typedef typename realType::Type REAL; 13 | public: 14 | hoCuTTSSolver():ttsSolver >(){ 15 | 16 | } 17 | 18 | virtual ~hoCuTTSSolver(){}; 19 | 20 | protected: 21 | virtual void solver_non_negativity_filter(hoCuNDArray *x,hoCuNDArray *g) 22 | { 23 | T* x_ptr = x->get_data_ptr(); 24 | T* g_ptr = g->get_data_ptr(); 25 | for (int i =0; i < x->get_number_of_elements(); i++){ 26 | if ( real(x_ptr[i]) <= REAL(0) && real(g_ptr[i]) < 0) g_ptr[i]=T(0); 27 | } 28 | 29 | } 30 | 31 | virtual void iteration_callback(hoCuNDArray* x,int i,REAL data_res,REAL reg_res){ 32 | if (i == 0){ 33 | std::ofstream textFile("residual.txt",std::ios::trunc); 34 | textFile << data_res << std::endl; 35 | } else{ 36 | std::ofstream textFile("residual.txt",std::ios::app); 37 | textFile << data_res << std::endl; 38 | } 39 | std::stringstream ss; 40 | ss << "iteration-" << i << ".real"; 41 | write_nd_array(x,ss.str().c_str()); 42 | }; 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /solvers/hoGPBBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gpBBSolver.h" 4 | #include "hoGTBLAS.h" 5 | namespace Gadgetron{ 6 | 7 | template class hoGPBBSolver: public gpBBSolver >{ 8 | public: 9 | typedef typename realType::type REAL; 10 | hoGPBBSolver():gpBBSolver >(){ 11 | 12 | } 13 | 14 | protected: 15 | virtual void solver_non_negativity_filter(hoNDArray *x,hoNDArray *g) 16 | { 17 | T* x_ptr = x->get_data_ptr(); 18 | T* g_ptr = g->get_data_ptr(); 19 | for (int i =0; i < x->get_number_of_elements(); i++){ 20 | if ( real(x_ptr[i]) < REAL(0) && real(g_ptr[i]) > 0) g_ptr[i]=T(0); 21 | } 22 | 23 | } 24 | 25 | virtual void solver_reciprocal_clamp( hoNDArray* x_arr, REAL threshold){ 26 | T* x = x_arr->get_data_ptr(); 27 | for (int i = 0; i < x_arr->get_number_of_elements(); i++){ 28 | if (real(x[i]) < threshold) x[i]= T(0); 29 | else x[i]= T(1)/x[i]; 30 | } 31 | } 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /solvers/hoNCGSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ncgSolver.h" 4 | #include "hoNDArray_math.h" 5 | #include "hoNDArray_fileio.h" 6 | #include "complext.h" 7 | 8 | namespace Gadgetron{ 9 | 10 | template class hoNCGSolver: public ncgSolver >{ 11 | typedef typename realType::Type REAL; 12 | public: 13 | hoNCGSolver():ncgSolver >(){ 14 | 15 | } 16 | 17 | virtual ~hoNCGSolver(){}; 18 | 19 | protected: 20 | virtual void solver_non_negativity_filter(hoNDArray *x,hoNDArray *g) 21 | { 22 | T* x_ptr = x->get_data_ptr(); 23 | T* g_ptr = g->get_data_ptr(); 24 | for (int i =0; i < x->get_number_of_elements(); i++){ 25 | if ( real(x_ptr[i]) <= REAL(0) && real(g_ptr[i]) > 0) g_ptr[i]=T(0); 26 | } 27 | 28 | } 29 | 30 | virtual void iteration_callback(hoNDArray* x,int i,REAL data_res,REAL reg_res){ 31 | // if (i == 0){ 32 | // std::ofstream textFile("residual.txt",std::ios::trunc); 33 | // textFile << data_res << std::endl; 34 | // } else{ 35 | // std::ofstream textFile("residual.txt",std::ios::app); 36 | // textFile << data_res << std::endl; 37 | // } 38 | // std::stringstream ss; 39 | // ss << "iteration-" << i << ".real"; 40 | // write_nd_array(x,ss.str().c_str()); 41 | }; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /solvers/hoOSCGPBBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "oscGPBBSolver.h" 4 | #include "hoNDArray_fileio.h" 5 | #include 6 | 7 | namespace Gadgetron{ 8 | 9 | template class hoOSCGPBBSolver : public oscGPBBSolver{ 10 | 11 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 12 | typedef typename realType::Type REAL; 13 | public: 14 | virtual ~hoOSCGPBBSolver(){}; 15 | protected: 16 | virtual void solver_non_negativity_filter(ARRAY_TYPE *xdata,ARRAY_TYPE *gdata){ 17 | ELEMENT_TYPE* x = xdata->get_data_ptr(); 18 | ELEMENT_TYPE* g = gdata->get_data_ptr(); 19 | for (int i = 0; i != xdata->get_number_of_elements(); ++i) 20 | if ( real(x[i]) <= REAL(0) && real(g[i]) > 0) g[i]=ELEMENT_TYPE(0); 21 | } 22 | 23 | virtual void iteration_callback(ARRAY_TYPE* x, int i){ 24 | std::stringstream ss; 25 | ss << "iteration-" << i << ".real"; 26 | write_nd_array(x,ss.str().c_str()); 27 | } 28 | }; 29 | /** 30 | * Specialization to disable class for cuNDArrays 31 | */ 32 | template class hoOSCGPBBSolver > { 33 | virtual void hoOSCGPBBSolver_only_works_for_host_arrays() =0; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /solvers/hoOSCGSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "osCGSolver.h" 4 | #include "hoNDArray_fileio.h" 5 | #include 6 | 7 | namespace Gadgetron{ 8 | 9 | template class hoOSCGSolver : public osCGSolver{ 10 | 11 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 12 | typedef typename realType::Type REAL; 13 | public: 14 | virtual ~hoOSCGSolver(){}; 15 | protected: 16 | virtual void solver_non_negativity_filter(ARRAY_TYPE *xdata,ARRAY_TYPE *gdata){ 17 | ELEMENT_TYPE* x = xdata->get_data_ptr(); 18 | ELEMENT_TYPE* g = gdata->get_data_ptr(); 19 | for (int i = 0; i != xdata->get_number_of_elements(); ++i) 20 | if ( real(x[i]) <= REAL(0) && real(g[i]) > 0) g[i]=ELEMENT_TYPE(0); 21 | } 22 | 23 | virtual void iteration_callback(ARRAY_TYPE* x, int i){ 24 | std::stringstream ss; 25 | ss << "iteration-" << i << ".real"; 26 | write_nd_array(x,ss.str().c_str()); 27 | } 28 | }; 29 | /** 30 | * Specialization to disable class for cuNDArrays 31 | */ 32 | template class hoOSCGSolver > { 33 | virtual void hoOSCGSolver_only_works_for_host_arrays() =0; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /solvers/hoOSGPBBSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "osGPBBSolver.h" 4 | #include "hoNDArray_fileio.h" 5 | #include 6 | 7 | namespace Gadgetron{ 8 | 9 | template class hoOSGPBBSolver : public osGPBBSolver{ 10 | 11 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 12 | typedef typename realType::Type REAL; 13 | public: 14 | virtual ~hoOSGPBBSolver(){}; 15 | protected: 16 | virtual void solver_non_negativity_filter(ARRAY_TYPE *xdata,ARRAY_TYPE *gdata){ 17 | ELEMENT_TYPE* x = xdata->get_data_ptr(); 18 | ELEMENT_TYPE* g = gdata->get_data_ptr(); 19 | for (int i = 0; i != xdata->get_number_of_elements(); ++i) 20 | if ( real(x[i]) <= REAL(0) && real(g[i]) > 0) g[i]=ELEMENT_TYPE(0); 21 | } 22 | 23 | virtual void iteration_callback(ARRAY_TYPE* x, int i){ 24 | std::stringstream ss; 25 | ss << "iteration-" << i << ".real"; 26 | write_nd_array(x,ss.str().c_str()); 27 | } 28 | }; 29 | /** 30 | * Specialization to disable class for cuNDArrays 31 | */ 32 | template class hoOSGPBBSolver > { 33 | virtual void hoOSGPBBSolver_only_works_for_host_arrays() =0; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /solvers/mlSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperatorSolver.h" 3 | 4 | namespace Gadgetron{ 5 | template class mlSolver 6 | : public linearOperatorSolver { 7 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 8 | typedef typename realType::type REAL; 9 | public: 10 | mlSolver(): linearOperatorSolver() { 11 | _iterations=10; 12 | } 13 | virtual ~mlSolver(){}; 14 | 15 | void set_max_iterations(int i){_iterations=i;} 16 | 17 | boost::shared_ptr solve(ARRAY_TYPE* in){ 18 | //boost::shared_ptr rhs = compute_rhs(in); 19 | if( this->encoding_operator_.get() == 0 ){ 20 | throw std::runtime_error( "Error: mlSolver::solve : no encoding operator is set" ); 21 | return boost::shared_ptr(); 22 | } 23 | 24 | // Get image space dimensions from the encoding operator 25 | // 26 | 27 | boost::shared_ptr< std::vector > image_dims = this->encoding_operator_->get_domain_dimensions(); 28 | if( image_dims->size() == 0 ){ 29 | throw std::runtime_error( "Error: mlSolver::solve : encoding operator has not set domain dimension" ); 30 | return boost::shared_ptr(); 31 | } 32 | 33 | ARRAY_TYPE * x = new ARRAY_TYPE; 34 | x->create(image_dims.get()); 35 | if (this->x0_.get()){ 36 | *x = *(this->x0_.get()); 37 | } else { 38 | x->fill(ELEMENT_TYPE(1)); 39 | } 40 | 41 | ARRAY_TYPE tmp_image; 42 | tmp_image.create(image_dims.get()); 43 | 44 | ARRAY_TYPE ones_image; 45 | ones_image.create(image_dims.get()); 46 | 47 | 48 | 49 | ARRAY_TYPE tmp_projection; 50 | tmp_projection.create(in->get_dimensions().get()); 51 | tmp_projection.fill(ELEMENT_TYPE(1)); 52 | this->encoding_operator_->mult_MH(&tmp_projection,&ones_image,false); 53 | 54 | clamp_min(&ones_image,ELEMENT_TYPE(1e-6)); 55 | ones_image.reciprocal(); 56 | 57 | clamp_max(&ones_image,ELEMENT_TYPE(1e6)); 58 | 59 | for (int i =0; i < _iterations; i++){ 60 | this->encoding_operator_->mult_M(x,&tmp_projection,false); 61 | tmp_projection += ELEMENT_TYPE(1); 62 | tmp_projection.reciprocal(); 63 | tmp_projection *= *in; 64 | this->encoding_operator_->mult_MH(&tmp_projection,&tmp_image,false); 65 | tmp_image *= ones_image; 66 | *x *= tmp_image; 67 | std::cout << "Iteration: " << i << std::endl; 68 | 69 | 70 | } 71 | 72 | return boost::shared_ptr(x); 73 | } 74 | virtual void add_regularization_operator( boost::shared_ptr< linearOperator > op){ 75 | std::cout << "Error mlSolver::add_regularization_operator - SART Solver does NOT support regularization operators." << std::endl; 76 | } 77 | 78 | 79 | protected: 80 | int _iterations; 81 | 82 | 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /solvers/sartSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "linearOperatorSolver.h" 3 | 4 | namespace Gadgetron{ 5 | template class sartSolver 6 | : public linearOperatorSolver { 7 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 8 | typedef typename realType::type REAL; 9 | public: 10 | sartSolver(): linearOperatorSolver() { 11 | _iterations=10; 12 | _beta = REAL(0.8); 13 | non_negativity_=false; 14 | } 15 | virtual ~sartSolver(){}; 16 | 17 | void set_max_iterations(int i){_iterations=i;} 18 | void set_non_negativity_constraint(bool neg){non_negativity_=neg;} 19 | 20 | boost::shared_ptr solve(ARRAY_TYPE* in){ 21 | //boost::shared_ptr rhs = compute_rhs(in); 22 | if( this->encoding_operator_.get() == 0 ){ 23 | throw std::runtime_error( "Error: cgSolver::compute_rhs : no encoding operator is set" ); 24 | return boost::shared_ptr(); 25 | } 26 | 27 | // Get image space dimensions from the encoding operator 28 | // 29 | 30 | boost::shared_ptr< std::vector > image_dims = this->encoding_operator_->get_domain_dimensions(); 31 | if( image_dims->size() == 0 ){ 32 | throw std::runtime_error( "Error: cgSolver::compute_rhs : encoding operator has not set domain dimension" ); 33 | return boost::shared_ptr(); 34 | } 35 | 36 | ARRAY_TYPE * x = new ARRAY_TYPE; 37 | x->create(image_dims.get()); 38 | if (this->x0_.get()){ 39 | *x = *(this->x0_.get()); 40 | } else { 41 | x->clear(); 42 | } 43 | 44 | 45 | 46 | ARRAY_TYPE ones_projection(in->get_dimensions().get()); 47 | 48 | ARRAY_TYPE tmp_image(image_dims.get()); 49 | 50 | tmp_image.fill(ELEMENT_TYPE(1)); 51 | this->encoding_operator_->mult_M(&tmp_image,&ones_projection,false); 52 | 53 | clamp_min(&ones_projection,ELEMENT_TYPE(1e-6)); 54 | ones_projection.reciprocal(); 55 | 56 | 57 | 58 | ARRAY_TYPE ones_image(image_dims.get()); 59 | 60 | 61 | ARRAY_TYPE tmp_projection(in->get_dimensions().get()); 62 | tmp_projection.fill(ELEMENT_TYPE(1)); 63 | this->encoding_operator_->mult_MH(&tmp_projection,&ones_image,false); 64 | clamp_min(&ones_image,ELEMENT_TYPE(1e-6)); 65 | ones_image.reciprocal(); 66 | 67 | for (int i =0; i < _iterations; i++){ 68 | this->encoding_operator_->mult_M(x,&tmp_projection,false); 69 | axpy(ELEMENT_TYPE(-1),in,&tmp_projection); 70 | tmp_projection *= ELEMENT_TYPE(-1); 71 | tmp_projection *= ones_projection; 72 | this->encoding_operator_->mult_MH(&tmp_projection,&tmp_image,false); 73 | tmp_image *= ones_image; 74 | axpy(ELEMENT_TYPE(1),&tmp_image,x); 75 | if( this->output_mode_ >= solver::OUTPUT_VERBOSE ){ 76 | std::cout << "Iteration " <(x); 85 | } 86 | virtual void add_regularization_operator( boost::shared_ptr< linearOperator > op){ 87 | std::cout << "Error sartSolver::add_regularization_operator - SART Solver does NOT support regularization operators." << std::endl; 88 | } 89 | 90 | 91 | protected: 92 | int _iterations; 93 | REAL _beta; 94 | bool non_negativity_; 95 | }; 96 | } 97 | -------------------------------------------------------------------------------- /solvers/solver_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "complext.h" 3 | #include "hoCuNDArray.h" 4 | #include "cuNDArray.h" 5 | 6 | namespace Gadgetron{ 7 | 8 | template void solver_non_negativity_filter(cuNDArray* x , cuNDArray* g); 9 | 10 | template void solver_non_negativity_filter(hoCuNDArray* x , hoCuNDArray* g); 11 | 12 | 13 | template void shrink_diff(cuNDArray* in_out, cuNDArray * diff, typename realType::Type gamma); 14 | 15 | template void hard_shrink(cuNDArray* in_out, typename realType::Type gamma); 16 | template void save_nd_array(cuNDArray* array, std::string s){ 17 | write_nd_array(array->to_host().get(),s.c_str()); 18 | } 19 | 20 | template void save_nd_array(hoNDArray* array, std::string s){ 21 | write_nd_array(array,s.c_str()); 22 | } 23 | 24 | template void huber_norm(cuNDArray*,cuNDArray*,cuNDArray*,T); 25 | 26 | template< class T> void calcC(cuNDArray* in_out,cuNDArray* b); 27 | template< class T> void exp_inv_inplace(cuNDArray* in_out); 28 | } 29 | -------------------------------------------------------------------------------- /solvers/subsetConverter2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * subsetConverter.h 3 | * 4 | * Created on: Dec 10, 2015 5 | * Author: dch 6 | */ 7 | 8 | #ifndef SUBSETCONVERTER_H_ 9 | #define SUBSETCONVERTER_H_ 10 | 11 | #include "subsetOperator.h" 12 | 13 | namespace Gadgetron { 14 | template class subsetConverter: public subsetOperator{ 15 | private: 16 | typedef typename ARRAY_TYPE::element_type ELEMENT_TYPE; 17 | typedef typename realType::Type REAL; 18 | public: 19 | 20 | subsetConverter(boost::shared_ptr > op_) : op(op_),subsetOperator(){}; 21 | 22 | virtual ~subsetConverter(){}; 23 | virtual void mult_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 24 | op->mult_M(in,out,accumulate); 25 | } 26 | virtual void mult_MH(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 27 | op->mult_MH(in,out,accumulate); 28 | } 29 | virtual void mult_MH_M(ARRAY_TYPE* in, ARRAY_TYPE* out, int subset, bool accumulate){ 30 | op->mult_MH_M(in,out,accumulate); 31 | } 32 | 33 | 34 | virtual boost::shared_ptr< std::vector > get_codomain_dimensions(int subset){ 35 | return op->get_codomain_dimensions(); 36 | } 37 | /* 38 | virtual void set_codomain_subsets(std::vector< std::vector > & _dims){ 39 | codomain_dimensions = std::vector< std::vector >(_dims); 40 | } 41 | */ 42 | int get_number_of_subsets(){return number_of_subsets;} 43 | 44 | protected: 45 | boost::shared_ptr > op; 46 | int number_of_subsets; 47 | 48 | }; 49 | 50 | } 51 | 52 | #endif /* SUBSETCONVERTER_H_ */ 53 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ENABLE_TESTING() 2 | 3 | if(WIN32) 4 | link_directories(${Boost_LIBRARY_DIRS}) 5 | endif(WIN32) 6 | 7 | include_directories( 8 | ${CMAKE_SOURCE_DIR}/operators 9 | ${Boost_INCLUDE_DIR} 10 | ${CUDA_INCLUDE_DIRS} 11 | ${GTEST_INCLUDE_DIRS} 12 | ) 13 | #cuda_add_executable(test_all 14 | # tests.cpp 15 | # waveletTest.cpp 16 | # ) 17 | 18 | #target_link_libraries(test_all 19 | # gadgetron_toolbox_cpucore 20 | # gadgetron_toolbox_cpucore_math 21 | # gadgetron_toolbox_gpucore 22 | # tomography_operators 23 | # ${BOOST_LIBRARIES} 24 | # ${GTEST_LIBRARIES} 25 | # ${CUDA_LIBRARIES} 26 | # ${CULA_LIBRARIES} 27 | # ) 28 | 29 | #add_test(test_all test_all) 30 | -------------------------------------------------------------------------------- /test/tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * tests.cpp 3 | * 4 | * Created on: Feb 28, 2013 5 | * Author: Dae 6 | */ 7 | 8 | #include 9 | 10 | int main(int argc, char **argv) { 11 | ::testing::InitGoogleTest(&argc, argv); 12 | return RUN_ALL_TESTS(); 13 | } 14 | -------------------------------------------------------------------------------- /xray/CBSubsetOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * CBSubsetOperator.h 4 | * 5 | * Created on: Feb 12, 2015 6 | * Author: u051747 7 | */ 8 | 9 | #pragma once 10 | #include "subsetOperator.h" 11 | #include 12 | #include 13 | #include "CBCT_acquisition.h" 14 | #include "cuConebeamProjectionOperator.h" 15 | #include "hoCuConebeamProjectionOperator.h" 16 | namespace Gadgetron { 17 | 18 | template class T> struct conebeamProjectionOperator{}; 19 | 20 | template<> struct conebeamProjectionOperator{ 21 | using type = hoCuConebeamProjectionOperator; 22 | }; 23 | 24 | template<> struct conebeamProjectionOperator{ 25 | using type = cuConebeamProjectionOperator; 26 | }; 27 | 28 | 29 | 30 | template class ARRAY> class CBSubsetOperator: public Gadgetron::subsetOperator> { 31 | public: 32 | CBSubsetOperator(int subsets); 33 | CBSubsetOperator() : CBSubsetOperator(1) {}; 34 | virtual ~CBSubsetOperator(); 35 | 36 | virtual void mult_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 37 | virtual void mult_MH(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 38 | virtual void mult_MH_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 39 | 40 | 41 | virtual boost::shared_ptr > get_codomain_dimensions(int subset) override; 42 | 43 | virtual void set_domain_dimensions(std::vector* dims) override { 44 | linearOperator>::set_domain_dimensions(dims); 45 | for (auto op : operators) 46 | op->set_domain_dimensions(dims); 47 | } 48 | void setup(boost::shared_ptr acq, boost::shared_ptr, floatd3 is_dims_in_mm); 49 | void setup(boost::shared_ptr acq, floatd3 is_dims_in_mm); 50 | boost::shared_ptr> calculate_mask(boost::shared_ptr > projections, float limit); 51 | 52 | void offset_correct(ARRAY*); 53 | void set_use_offset_correction(bool use){ 54 | for (auto op : operators) op->set_use_offset_correction(use); 55 | } 56 | 57 | void set_mask(boost::shared_ptr > mask){ 58 | for (auto op : operators) 59 | op->set_mask(mask); 60 | } 61 | 62 | 63 | protected: 64 | 65 | boost::shared_ptr> permute_projections(boost::shared_ptr> projections, std::vector & permutations); 66 | std::vector::type>> operators; 67 | 68 | std::vector > > projection_dims; 69 | std::vector > angles; 70 | std::vector > offsets; 71 | std::vector permutations; //Projection permutations 72 | }; 73 | 74 | } /* namespace Gadgetron */ 75 | -------------------------------------------------------------------------------- /xray/CBSubsetWeightOperator.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 31/03/17. 3 | // 4 | 5 | #ifndef GT_TOMOGRAPHY_CBSUBSETWEIGHTOPERATOR_H 6 | #define GT_TOMOGRAPHY_CBSUBSETWEIGHTOPERATOR_H 7 | 8 | #include "CBSubsetOperator.h" 9 | #include 10 | namespace Gadgetron { 11 | template class ARRAY> class CBSubsetWeightOperator : public CBSubsetOperator { 12 | 13 | public: 14 | CBSubsetWeightOperator(int i) : CBSubsetOperator(i){} 15 | CBSubsetWeightOperator() : CBSubsetOperator(){} 16 | 17 | void setup(boost::shared_ptr acq, boost::shared_ptr binning, floatd3 is_dims_in_mm, 18 | boost::shared_ptr> projection_weights) { 19 | 20 | *acq->get_projections() *= *projection_weights; 21 | CBSubsetOperator::setup(acq,binning,is_dims_in_mm); 22 | 23 | auto permuted_weights = this->permute_projections(projection_weights,this->permutations); 24 | weights = ARRAY(*permuted_weights); 25 | std::cout << " Weight dims "; 26 | auto dims = *weights.get_dimensions(); 27 | for (auto d : dims) std::cout << d << " "; 28 | std::cout << std::endl; 29 | subset_weights = this->projection_subsets(&weights); 30 | 31 | } 32 | 33 | virtual void mult_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override{ 34 | ARRAY *tmp_out = out; 35 | if (accumulate) tmp_out = new ARRAY(out->get_dimensions()); 36 | 37 | CBSubsetOperator::mult_M(in,tmp_out,subset,false); 38 | *tmp_out *= *subset_weights[subset]; 39 | if (accumulate) { 40 | *out += *tmp_out; 41 | delete(tmp_out); 42 | } 43 | 44 | } 45 | virtual void mult_MH(ARRAY* in, ARRAY * out,int subset, bool accumulate) override { 46 | ARRAY tmp_in(*in); 47 | tmp_in *= *subset_weights[subset]; 48 | CBSubsetOperator::mult_MH(&tmp_in,out,subset,accumulate); 49 | 50 | } 51 | virtual void mult_MH_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override { 52 | 53 | auto codom = this->get_codomain_dimensions(subset); 54 | ARRAY tmp(codom); 55 | this->mult_M(in,&tmp,subset,false); 56 | this->mult_MH(&tmp,out,subset,accumulate); 57 | 58 | } 59 | protected: 60 | 61 | ARRAY weights; 62 | std::vector>> subset_weights; 63 | }; 64 | } 65 | 66 | 67 | #endif //GT_TOMOGRAPHY_CBSUBSETWEIGHTOPERATOR_H 68 | -------------------------------------------------------------------------------- /xray/CTProjectionOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cuCTProjectionOperator.h 3 | 4 | * 5 | * Created on: Feb 18, 2015 6 | * Author: u051747 7 | */ 8 | #pragma once 9 | #include 10 | #include 11 | 12 | #include 13 | #include "CT_acquisition.h" 14 | #include "CBCT_binning.h" 15 | #include 16 | #include "vector_td.h" 17 | 18 | 19 | namespace Gadgetron { 20 | 21 | template< template class ARRAY> class CTProjectionOperator: public Gadgetron::linearOperator> { 22 | public: 23 | CTProjectionOperator(); 24 | virtual ~CTProjectionOperator(); 25 | 26 | virtual void mult_M(ARRAY* input, ARRAY* output, bool accumulate=false); 27 | virtual void mult_MH(ARRAY* input, ARRAY* output, bool accumulate=false); 28 | 29 | void setup(boost::shared_ptr acquisition, floatd3 is_dims_in_mm); 30 | void setup(boost::shared_ptr acquisition, boost::shared_ptr> weights,floatd3 is_dims_in_mm); 31 | void setup(boost::shared_ptr acquisition, boost::shared_ptr binnning,floatd3 is_dims_in_mm); 32 | 33 | 34 | protected: 35 | 36 | /** 37 | * Calculates the start and end index of the projections fitting to each projection 38 | */ 39 | std::vector calculate_slice_indices(CT_acquisition &acquisition); 40 | 41 | boost::shared_ptr binning; 42 | floatd3 is_dims_in_mm; //Image size in mm 43 | floatd2 ps_spacing; // Spacing between projection elements 44 | float ADD; //Aparture detector distance 45 | float samples_per_pixel_; //Number of samples used for the line integrals, divided by largest image slice dimensions 46 | bool preprocessed_; 47 | std::vector> detector_focal_cyls; 48 | std::vector> focal_offset_cyls; 49 | std::vector> central_elements; 50 | std::vector> proj_indices; 51 | boost::shared_ptr> weights; 52 | 53 | 54 | }; 55 | 56 | } /* namespace Gadgetron */ 57 | -------------------------------------------------------------------------------- /xray/CTSubsetOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * CTSubsetOperator.h 4 | * 5 | * Created on: Feb 12, 2015 6 | * Author: u051747 7 | */ 8 | 9 | #pragma once 10 | #include "subsetOperator.h" 11 | #include 12 | #include 13 | #include "CBCT_acquisition.h" 14 | #include "cuConebeamProjectionOperator.h" 15 | #include "hoCuConebeamProjectionOperator.h" 16 | #include "CTProjectionOperator.h" 17 | namespace Gadgetron { 18 | 19 | 20 | 21 | //template<> struct ctProjectionOperator{ 22 | //using type = oCuConebeamProjectionOperator; 23 | //}; 24 | 25 | 26 | 27 | 28 | template class ARRAY> class CTSubsetOperator: public Gadgetron::subsetOperator> { 29 | public: 30 | CTSubsetOperator(int subsets); 31 | CTSubsetOperator() : CTSubsetOperator(1) {}; 32 | virtual ~CTSubsetOperator(); 33 | 34 | virtual void mult_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 35 | virtual void mult_MH(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 36 | virtual void mult_MH_M(ARRAY* in, ARRAY * out,int subset, bool accumulate) override; 37 | 38 | 39 | virtual boost::shared_ptr > get_codomain_dimensions(int subset) override; 40 | 41 | virtual void set_domain_dimensions(std::vector* dims) override { 42 | linearOperator>::set_domain_dimensions(dims); 43 | for (auto op : operators) 44 | op->set_domain_dimensions(dims); 45 | } 46 | 47 | boost::shared_ptr> setup(boost::shared_ptr acq, floatd3 is_dims_in_mm, boost::shared_ptr> weights= boost::shared_ptr>()); 48 | 49 | boost::shared_ptr> permute_projections(hoCuNDArray& projections, std::vector & permutations); 50 | 51 | std::vector permutations; 52 | 53 | protected: 54 | 55 | 56 | std::vector>> operators; 57 | //std::vector::type>> operators; 58 | 59 | std::vector > > projection_dims; 60 | 61 | }; 62 | 63 | } /* namespace Gadgetron */ 64 | -------------------------------------------------------------------------------- /xray/CT_acquisition.h: -------------------------------------------------------------------------------- 1 | #ifndef CT_ACQUISITION_H_ 2 | #define CT_ACQUISITION_H_ 3 | #pragma once 4 | #include "hoCuNDArray.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | namespace Gadgetron { 17 | struct CT_geometry { 18 | CT_geometry() : detectorFocalCenterAngularPosition(), detectorFocalCenterAxialPosition(), 19 | constantRadialDistance(), detectorCentralElement(), sourceAngularPositionShift(), 20 | sourceAxialPositionShift(), sourceRadialDistanceShift(){ 21 | } 22 | 23 | 24 | floatd2 detectorSize; 25 | 26 | std::vector detectorFocalCenterAngularPosition; 27 | std::vector detectorFocalCenterAxialPosition; 28 | std::vector detectorFocalRadialDistance; 29 | std::vector constantRadialDistance; 30 | std::vector detectorCentralElement; 31 | std::vector sourceAngularPositionShift; 32 | std::vector sourceAxialPositionShift; 33 | std::vector sourceRadialDistanceShift; 34 | }; 35 | 36 | class CT_acquisition { 37 | public: 38 | CT_acquisition() : projections(), geometry(){ 39 | 40 | } 41 | hoCuNDArray projections; 42 | hoCuNDArray photonStatistics; 43 | CT_geometry geometry; 44 | float calibration_factor; 45 | std::string StudyInstanceUID; 46 | std::string SeriesInstanceUID; 47 | size_t SeriesNumber; 48 | 49 | }; 50 | 51 | 52 | boost::shared_ptr read_dicom_projections(std::vector files, unsigned int remove_projs=0); 53 | void downscale_projections(boost::shared_ptr acq); 54 | 55 | 56 | } 57 | #endif -------------------------------------------------------------------------------- /xray/compare_images.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 13/03/17. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "mssim.h" 12 | 13 | namespace po = boost::program_options; 14 | 15 | using namespace Gadgetron; 16 | 17 | int main(int argc, char** argv) { 18 | 19 | std::string image_file; 20 | std::string reference_file; 21 | float sigma; 22 | po::options_description desc("Allowed options"); 23 | 24 | desc.add_options() 25 | ("help", "produce help message") 26 | ("image",po::value(&image_file)) 27 | ("gold",po::value(&reference_file)) 28 | ("sigma",po::value(&sigma)->default_value(1.5f)); 29 | 30 | 31 | 32 | po::variables_map vm; 33 | po::store(po::parse_command_line(argc, argv, desc), vm); 34 | po::notify(vm); 35 | 36 | auto image = read_nd_array(image_file.c_str()); 37 | auto gold = read_nd_array(reference_file.c_str()); 38 | 39 | 40 | 41 | auto dims = *image->get_dimensions(); 42 | size_t phases = dims[3]; 43 | 44 | std::vector results; 45 | 46 | 47 | std::vector dims3d(dims.begin(),dims.end()-1); 48 | 49 | size_t elements = std::accumulate(dims3d.begin(),dims3d.end(),1,std::multiplies()); 50 | 51 | for (size_t phase = 0; phase < phases; phase++){ 52 | hoNDArray image_view(dims3d,image->get_data_ptr()+phase*elements); 53 | hoNDArray ref_view(dims3d,gold->get_data_ptr()+phase*elements); 54 | 55 | cuNDArray cu_image(image_view); 56 | cuNDArray cu_ref(ref_view); 57 | 58 | 59 | results.push_back(mssim(&cu_image,&cu_ref,floatd3(sigma,sigma,sigma))); 60 | // 61 | // cu_image -= cu_ref; 62 | // 63 | // results.push_back(nrm2(&cu_image)); 64 | 65 | } 66 | 67 | 68 | float sum = std::accumulate(results.begin(),results.end(),0.0f)/results.size(); 69 | 70 | std::cout << sum << std::endl; 71 | // 72 | // for (auto r : results) 73 | // std::cout << r << " "; 74 | 75 | 76 | 77 | } 78 | 79 | -------------------------------------------------------------------------------- /xray/cuConebeamProjectionOperator.h: -------------------------------------------------------------------------------- 1 | /* 2 | * cuConebeamProjectionOperator.h 3 | 4 | * 5 | * Created on: Feb 18, 2015 6 | * Author: u051747 7 | */ 8 | #pragma once 9 | #include 10 | #include 11 | 12 | #include 13 | #include "CBCT_acquisition.h" 14 | #include "CBCT_binning.h" 15 | #include 16 | #include "vector_td.h" 17 | 18 | 19 | namespace Gadgetron { 20 | 21 | class cuConebeamProjectionOperator: public Gadgetron::linearOperator> { 22 | public: 23 | cuConebeamProjectionOperator(); 24 | virtual ~cuConebeamProjectionOperator(); 25 | 26 | virtual void mult_M(cuNDArray* input, cuNDArray* output, bool accumulate=false); 27 | virtual void mult_MH(cuNDArray* input, cuNDArray* output, bool accumulate=false); 28 | 29 | boost::shared_ptr> calculate_mask( cuNDArray* projections, float limit); 30 | void setup(boost::shared_ptr acquisition, floatd3 is_dims_in_mm, bool transform_angles = true); 31 | void setup(boost::shared_ptr acquisition, boost::shared_ptr binnning,floatd3 is_dims_in_mm, bool transform_angles = true); 32 | void offset_correct(cuNDArray*); 33 | bool get_use_offset_correction(){return use_offset_correction_;} 34 | void set_use_offset_correction(bool use){ use_offset_correction_ = use; allow_offset_correction_override_ = false;} 35 | 36 | void set_mask(boost::shared_ptr> m){ mask = m;} 37 | protected: 38 | boost::shared_ptr> permute_projections(boost::shared_ptr> projections,std::vector& permutations); 39 | std::vector new_order(std::vector>); 40 | boost::shared_ptr acquisition_; 41 | boost::shared_ptr binning_; 42 | std::vector > angles; 43 | std::vector > offsets; 44 | floatd3 is_dims_in_mm_; 45 | float samples_per_pixel_; 46 | bool use_fbp_; 47 | unsigned int projections_per_batch_; 48 | bool preprocessed_; 49 | bool short_scan_; 50 | bool use_offset_correction_; 51 | bool allow_offset_correction_override_; 52 | boost::shared_ptr> mask; 53 | }; 54 | 55 | } /* namespace Gadgetron */ 56 | -------------------------------------------------------------------------------- /xray/cuHSTVOFSolver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "opticalFlowOperator.h" 4 | #include "cuPartialDerivativeOperator.h" 5 | #include "cuCgSolver.h" 6 | namespace Gadgetron{ 7 | 8 | 9 | template class cuHSTVOFSolver : public multiresRegistrationSolver, D>{ 10 | public: 11 | cuHSTVOFSolver(){ 12 | 13 | OF = boost::shared_ptr(new OFOp); 14 | solver = boost::shared_ptr< cuCgSolver >(new cuCgSolver); 15 | solver->set_encoding_operator(OF); 16 | for (unsigned int i = 0; i < D; i++){ 17 | boost::shared_ptr > dx(new cuPartialDerivativeOperator(i)); 18 | solver->add_regularization_operator(dx); 19 | ops.push_back(dx); 20 | } 21 | } 22 | 23 | virtual ~cuHSTVOFSolver(){}; 24 | typedef opticalFlowOperator,cuPartialDerivativeOperator,D> OFOp; 25 | 26 | virtual void compute( cuNDArray *fixed_image, cuNDArray *moving_image, cuNDArray *stencil_image, boost::shared_ptr > &result ) 27 | { 28 | std::vector dims = *fixed_image->get_dimensions(); 29 | OF->set_codomain_dimensions(&dims); 30 | OF->set_images(fixed_image,moving_image); 31 | 32 | for (int i = 0; i < ops.size(); i++){ 33 | ops[i]->set_domain_dimensions(&dims); 34 | ops[i]->set_codomain_dimensions(&dims); 35 | ops[i]->set_weight(_alpha); 36 | } 37 | 38 | dims.push_back(D); 39 | OF->set_domain_dimensions(&dims); 40 | cuNDArray It(*fixed_image); 41 | It -= *moving_image; 42 | boost::shared_ptr > resOp = solver->solve(&It); 43 | 44 | if (result.get()) *result += *resOp; 45 | else result = resOp; 46 | } 47 | 48 | void set_alpha(T alpha){ 49 | _alpha = alpha; 50 | } 51 | 52 | boost::shared_ptr< cuCgSolver > get_solver(){ 53 | return solver; 54 | } 55 | 56 | protected: 57 | 58 | T _alpha; 59 | boost::shared_ptr< cuCgSolver > solver; 60 | boost::shared_ptr OF; 61 | std::vector > >ops; 62 | }; 63 | 64 | 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /xray/dicomCTWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include "CT_acquisition.h" 7 | 8 | namespace Gadgetron { 9 | 10 | void write_dicomCT(std::string dicomDir,hoNDArray* image, floatd3 imageDimensions, CT_acquisition * acquisition, float offset,int skip_proj=0); 11 | void write_binaryCT(std::string dicomDir,hoNDArray* image, floatd3 imageDimensions, CT_acquisition * acquisition, float offset,int skip_proj=0); 12 | } -------------------------------------------------------------------------------- /xray/dicomWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray.h" 4 | #include "cuNDArray.h" 5 | #include "vector_td.h" 6 | 7 | namespace Gadgetron { 8 | void write_dicom(hoNDArray* image, const std::string& command_line, floatd3 imageDimensions); 9 | 10 | 11 | void write_dicom(cuNDArray* image, const std::string& command_line, floatd3 imageDimensions){ 12 | auto array = image->to_host(); 13 | write_dicom(array.get(),command_line,imageDimensions); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /xray/float3x3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //#define SINCOSF __sincosf // fast math 4 | #define SINCOSF sincosf 5 | #include "vector_td_utilities.h" 6 | 7 | namespace Gadgetron{ 8 | 9 | struct float3x3 { 10 | floatd3 row0; 11 | floatd3 row1; 12 | floatd3 row2; 13 | }; 14 | 15 | __inline__ __host__ __device__ 16 | float3x3 make_float3x3(float v0, float v1, float v2, 17 | float v3, float v4, float v5, 18 | float v6, float v7, float v8) { 19 | float3x3 m; 20 | m.row0 = floatd3(v0, v1, v2); 21 | m.row1 = floatd3(v3, v4, v5); 22 | m.row2 = floatd3(v6, v7, v8); 23 | return m; 24 | } 25 | 26 | __inline__ __device__ 27 | floatd3 mul(const float3x3 & m, const floatd3 & v) { 28 | return floatd3( dot(m.row0,v), dot(m.row1,v), dot(m.row2,v) ); 29 | } 30 | 31 | 32 | __inline__ __device__ float3x3 calcRotationMatrixAroundX(float angle) { 33 | float cos_angle, sin_angle; 34 | SINCOSF(angle, &sin_angle, &cos_angle); 35 | 36 | // Build projection rotation matrix 37 | float3x3 rotation = make_float3x3(1, 0, 0, 38 | 0, cos_angle, -sin_angle, 39 | 0, sin_angle, cos_angle); 40 | return rotation; 41 | } 42 | 43 | __inline__ __device__ float3x3 calcRotationMatrixAroundY(float angle) { 44 | float cos_angle, sin_angle; 45 | SINCOSF(angle, &sin_angle, &cos_angle); 46 | 47 | // Build projection rotation matrix 48 | float3x3 rotation = make_float3x3( cos_angle, 0, sin_angle, 49 | 0, 1, 0, 50 | -sin_angle, 0, cos_angle); 51 | return rotation; 52 | } 53 | 54 | __inline__ __host__ __device__ float3x3 calcRotationMatrixAroundZ(float angle) { 55 | float cos_angle, sin_angle; 56 | sincosf(angle, &sin_angle, &cos_angle); 57 | 58 | // Build projection rotation matrix 59 | float3x3 rotation = make_float3x3(cos_angle, -sin_angle, 0, 60 | sin_angle, cos_angle, 0, 61 | 0, 0, 1); 62 | return rotation; 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /xray/hoCuOFPartialDerivativeOperator.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 12/02/16. 3 | // 4 | 5 | #include "hoCuOFPartialDerivativeOperator.h" 6 | #include 7 | using namespace Gadgetron; 8 | 9 | 10 | template void Gadgetron::hoCuOFPartialDerivativeOperator::set_displacement_field(boost::shared_ptr> vf) { 11 | 12 | size_t nphases = vf->get_size(4); 13 | 14 | auto vdims = *vf->get_dimensions(); 15 | vdims.pop_back(); 16 | size_t elements = vf->get_number_of_elements()/nphases; 17 | std::cout << "Nphases " << nphases << std::endl; 18 | //Rs = std::vector>(nphases,hoLinearResampleOperator_eigen()); 19 | Rs = std::vector>(); 20 | 21 | for (auto i = 0u; i < nphases; i++){ 22 | Rs.emplace_back(); 23 | std::cout << "Setting displacementfield " << i << std::endl; 24 | auto array_view = boost::make_shared>(vdims,vf->get_data_ptr()+i*elements); 25 | auto cu_array_view = boost::make_shared>(*array_view); 26 | Rs.back().set_displacement_field(cu_array_view); 27 | Rs.back().mult_MH_preprocess(); 28 | } 29 | 30 | 31 | } 32 | 33 | template void hoCuOFPartialDerivativeOperator::mult_M(hoCuNDArray *in, hoCuNDArray *out, bool accumulate) { 34 | if (!in->dimensions_equal(out)) throw std::runtime_error("Dimensions of in and out must be equal"); 35 | if (in->get_size(3) != Rs.size()) throw std::runtime_error("Temporal dimension must match number of vector fields"); 36 | auto dims3d = *in->get_dimensions(); 37 | dims3d.pop_back(); 38 | size_t elements = in->get_number_of_elements()/in->get_size(3); 39 | if (!accumulate) clear(out); 40 | for (int i = 0u; i < Rs.size(); i++){ 41 | auto in_view = hoCuNDArray(dims3d,in->get_data_ptr()+i*elements); 42 | auto cu_in = cuNDArray(in_view); 43 | auto cu_in_copy = cu_in; 44 | 45 | Rs[i].mult_M(&cu_in,&cu_in_copy); 46 | 47 | auto in_copy = cu_in_copy.to_host(); 48 | 49 | auto in_view2 = hoCuNDArray(dims3d,in->get_data_ptr()+((i+1)%Rs.size())*elements); 50 | auto out_view = hoCuNDArray(dims3d,out->get_data_ptr()+i*elements); 51 | out_view += *in_copy; 52 | out_view -= in_view2; 53 | } 54 | } 55 | template void hoCuOFPartialDerivativeOperator::mult_MH(hoCuNDArray *in, hoCuNDArray *out, bool accumulate) { 56 | if (!in->dimensions_equal(out)) throw std::runtime_error("Dimensions of in and out must be equal"); 57 | auto dims3d = *in->get_dimensions(); 58 | dims3d.pop_back(); 59 | size_t elements = in->get_number_of_elements()/in->get_size(3); 60 | for (int i = 0u; i < Rs.size(); i++){ 61 | auto in_view = hoCuNDArray(dims3d,in->get_data_ptr()+i*elements); 62 | auto in_view2 = hoCuNDArray(dims3d,in->get_data_ptr()+((i-1+Rs.size())%Rs.size())*elements); 63 | auto cu_in2 = cuNDArray(in_view2); 64 | 65 | auto out_view = hoCuNDArray(dims3d,out->get_data_ptr()+i*elements); 66 | 67 | auto cu_in = cuNDArray(in_view); 68 | auto cu_out = cuNDArray(out_view); 69 | Rs[i].mult_MH(&cu_in,&cu_out,accumulate); 70 | axpy(T(-1),&cu_in2,&cu_out); 71 | //Rs[(i-1)%Rs.size()].mult_MH(&cu_in2,&cu_out,true); 72 | cu_out.to_host(&out_view); 73 | //out_view = in_copy; 74 | } 75 | } 76 | 77 | 78 | template class hoCuOFPartialDerivativeOperator; -------------------------------------------------------------------------------- /xray/hoCuOFPartialDerivativeOperator.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 12/02/16. 3 | // 4 | 5 | #ifndef GT_TOMOGRAPHY_HOCUOFPARTIALDERIVATIVEOPERATOR_H 6 | #define GT_TOMOGRAPHY_HOCUOFPARTIALDERIVATIVEOPERATOR_H 7 | 8 | #include 9 | #include 10 | #include "hoLinearResampleOperator_eigen.h" 11 | #include "cuLinearResampleOperator.h" 12 | 13 | namespace Gadgetron { 14 | template 15 | class hoCuOFPartialDerivativeOperator : public linearOperator> { 16 | public: 17 | hoCuOFPartialDerivativeOperator() : linearOperator>() {}; 18 | 19 | void set_displacement_field(boost::shared_ptr > vf); 20 | 21 | virtual void mult_MH(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) override; 22 | 23 | virtual void mult_M(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) override; 24 | 25 | protected: 26 | //std::vector> Rs; 27 | std::vector> Rs; 28 | 29 | }; 30 | } 31 | 32 | 33 | #endif //GT_TOMOGRAPHY_HOCUOFPARTIALDERIVATIVEOPERATOR_H 34 | -------------------------------------------------------------------------------- /xray/hoCuTVOFPartialDerivativeOperator.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 12/02/16. 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "hoLinearResampleOperator_eigen.h" 10 | #include "cuLinearResampleOperator.h" 11 | #include "hoCuOFPartialDerivativeOperator.h" 12 | 13 | namespace Gadgetron { 14 | template 15 | class hoCuTVOFPartialDerivativeOperator : public hoCuOFPartialDerivativeOperator { 16 | typedef hoCuOFPartialDerivativeOperator parent; 17 | public: 18 | hoCuTVOFPartialDerivativeOperator() : hoCuOFPartialDerivativeOperator(), dX(0), dY(1), dZ(1) {}; 19 | 20 | 21 | virtual void mult_M(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) override{ 22 | auto tmp_out = *in; 23 | std::cout << "Number of elements" << in->get_number_of_elements() << " " << out->get_number_of_elements() << std::endl; 24 | 25 | if (in->get_number_of_elements()*3 != out->get_number_of_elements()) 26 | throw std::runtime_error("Input and output is inconsistent"); 27 | 28 | parent::mult_M(in,&tmp_out,false); 29 | 30 | size_t elements = in->get_number_of_elements(); 31 | hoCuNDArray out_viewX(in->get_dimensions(),out->get_data_ptr()); 32 | hoCuNDArray out_viewY(in->get_dimensions(),out->get_data_ptr()+elements); 33 | hoCuNDArray out_viewZ(in->get_dimensions(),out->get_data_ptr()+2*elements); 34 | dX.mult_M(&tmp_out, &out_viewX,accumulate); 35 | dY.mult_M(&tmp_out, &out_viewY,accumulate); 36 | dZ.mult_M(&tmp_out, &out_viewZ,accumulate); 37 | 38 | 39 | 40 | }; 41 | 42 | virtual void mult_MH(hoCuNDArray* in, hoCuNDArray* out, bool accumulate) override { 43 | 44 | hoCuNDArray tmp_out(out->get_dimensions()); 45 | size_t elements = out->get_number_of_elements(); 46 | hoCuNDArray in_viewX(out->get_dimensions(),in->get_data_ptr()); 47 | hoCuNDArray in_viewY(out->get_dimensions(),in->get_data_ptr()+elements); 48 | hoCuNDArray in_viewZ(out->get_dimensions(),in->get_data_ptr()+2*elements); 49 | dX.mult_MH(&in_viewX, &tmp_out,false); 50 | dY.mult_MH(&in_viewY, &tmp_out,true); 51 | dZ.mult_MH(&in_viewZ, &tmp_out,true); 52 | 53 | parent::mult_MH(&tmp_out,out,accumulate); 54 | 55 | 56 | } 57 | 58 | hoCuPartialDerivativeOperator dX; 59 | hoCuPartialDerivativeOperator dY; 60 | hoCuPartialDerivativeOperator dZ; 61 | 62 | 63 | }; 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /xray/hoLinearResampleOperator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray_math.h" 4 | #include "resampleOperator.h" 5 | #include "complext.h" 6 | #include "hoArmadillo.h" 7 | #include 8 | namespace Gadgetron{ 9 | 10 | template 11 | class hoLinearResampleOperator : public resampleOperator::Type>, hoNDArray > 12 | { 13 | public: 14 | 15 | hoLinearResampleOperator() : resampleOperator::Type>, hoNDArray >() {} 16 | virtual ~hoLinearResampleOperator() {} 17 | 18 | virtual void mult_M( hoNDArray *in, hoNDArray *out, bool accumulate = false); 19 | virtual void mult_MH( hoNDArray *in, hoNDArray *out, bool accumulate = false); 20 | virtual void set_displacement_field( boost::shared_ptr< hoNDArray::Type> > offsets ); 21 | virtual void reset(); 22 | 23 | private: 24 | inline bool is_border_pixel( typename reald::Type,D>::Type co, typename uint64d::Type dims ); 25 | inline unsigned int get_num_neighbors(); 26 | 27 | protected: 28 | arma::SpMat::Type> R_T_; //Contains the TRANSPOSED resampling matrix. 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /xray/hoLinearResampleOperator_eigen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "hoNDArray_math.h" 4 | 5 | #include "resampleOperator.h" 6 | #include "complext.h" 7 | 8 | #include 9 | #define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET 10 | #include 11 | 12 | namespace Gadgetron{ 13 | 14 | template 15 | class hoLinearResampleOperator_eigen : public resampleOperator::Type>, hoNDArray > 16 | { 17 | public: 18 | 19 | hoLinearResampleOperator_eigen() : resampleOperator::Type>, hoNDArray >() {} 20 | virtual ~hoLinearResampleOperator_eigen() {} 21 | 22 | virtual void mult_M( hoNDArray *in, hoNDArray *out, bool accumulate = false); 23 | virtual void mult_MH( hoNDArray *in, hoNDArray *out, bool accumulate = false); 24 | virtual void set_displacement_field( boost::shared_ptr< hoNDArray::Type> > displacements ); 25 | 26 | virtual unsigned int get_temporal_dimension_size() { return temporal_dim_size_; } 27 | 28 | 29 | private: 30 | inline bool is_border_pixel( typename reald::Type,D>::Type co, typename uint64d::Type dims ); 31 | inline unsigned int get_num_neighbors(); 32 | 33 | protected: 34 | boost::shared_ptr< Eigen::SparseMatrix::Type> > R_; 35 | unsigned int temporal_dim_size_; 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /xray/mssim.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 13/03/17. 3 | // 4 | 5 | #include "mssim.h" 6 | #include 7 | #include "cuGaussianFilterOperator.h" 8 | #include 9 | #include 10 | 11 | using namespace Gadgetron; 12 | 13 | 14 | static cuNDArray CS(cuNDArray* X, cuNDArray * Y, floatd3 sigma){ 15 | cuGaussianFilterOperator gauss; 16 | gauss.set_sigma(sigma); 17 | float K2 = 0.03; 18 | 19 | float data_range = max(Y)-min(Y); 20 | 21 | cuNDArray ux(X->get_dimensions()); 22 | gauss.mult_M(X,&ux); 23 | 24 | cuNDArray uy(Y->get_dimensions()); 25 | gauss.mult_M(Y,&uy); 26 | 27 | 28 | cuNDArray tmp(*X); 29 | tmp *= *X; 30 | cuNDArray XX(Y->get_dimensions()); 31 | gauss.mult_M(&tmp,&XX); 32 | 33 | tmp = *Y; 34 | tmp *= *Y; 35 | 36 | cuNDArray YY(Y->get_dimensions()); 37 | gauss.mult_M(&tmp,&YY); 38 | 39 | tmp = *Y; 40 | tmp *= *X; 41 | 42 | 43 | cuNDArray YX(Y->get_dimensions()); 44 | gauss.mult_M(&tmp,&YX); 45 | 46 | 47 | cuNDArray uxuy = ux; 48 | uxuy *= uy; 49 | 50 | ux *= ux; 51 | uy *= uy; 52 | 53 | XX -= ux; 54 | 55 | YY -= uy; 56 | 57 | YX -= uxuy; 58 | 59 | float c2 = std::pow(K2*data_range,2); 60 | 61 | YX *= float(2); 62 | YX += c2; 63 | 64 | XX += YY; 65 | XX += c2; 66 | 67 | 68 | YX /= XX; 69 | 70 | return YX; 71 | 72 | 73 | 74 | } 75 | 76 | 77 | float Gadgetron::mssim(cuNDArray *image, cuNDArray *reference, floatd3 sigma, int scales) { 78 | cuNDArray S(image->get_dimensions()); 79 | fill(&S,1.0f); 80 | 81 | for (int i = 0; i < scales; i++){ 82 | 83 | auto tmp = CS(image,reference,sigma*float(std::pow(2.0f,i))); 84 | S *= tmp; 85 | } 86 | 87 | 88 | cuGaussianFilterOperator gauss; 89 | gauss.set_sigma(sigma*float(std::pow(2.0f,scales-1))); 90 | 91 | float K1 = 0.01; 92 | 93 | 94 | 95 | float data_range = max(reference)-min(reference); 96 | float c1 = std::pow(K1*data_range,2); 97 | cuNDArray ux(image->get_dimensions()); 98 | gauss.mult_M(image,&ux); 99 | 100 | 101 | cuNDArray uy(image->get_dimensions()); 102 | gauss.mult_M(reference,&uy); 103 | 104 | 105 | cuNDArray A(ux); 106 | A *= uy; 107 | A *= float(2); 108 | A += c1; 109 | 110 | ux *= ux; 111 | uy *= uy; 112 | ux += uy; 113 | ux += c1; 114 | 115 | S *= A; 116 | S /= ux; 117 | 118 | return mean(&S); 119 | 120 | 121 | } 122 | -------------------------------------------------------------------------------- /xray/mssim.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | namespace Gadgetron{ 5 | 6 | 7 | float mssim(cuNDArray* image,cuNDArray* reference,floatd3 sigma, int scales=3); 8 | 9 | } -------------------------------------------------------------------------------- /xray/projection_utils.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 19/12/16. 3 | // 4 | 5 | #include 6 | #include "projection_utils.h" 7 | 8 | using namespace Gadgetron; 9 | 10 | cuNDArray Gadgetron::downsample_projections(cuNDArray *image, float factorX, float factorY) { 11 | 12 | NppiSize size = {image->get_size(0), image->get_size(1)}; 13 | NppiPoint offset = {0, 0}; 14 | NppiRect roi = {0,0,size.width,size.height}; 15 | 16 | auto result_size = std::vector{size_t(image->get_size(0) * factorX), 17 | size_t(image->get_size(1) * factorY), image->get_size(2)}; 18 | 19 | cuNDArray result(result_size); 20 | 21 | 22 | NppiSize output_size = {result_size[0], result_size[1]}; 23 | NppiRect output_roi = {0,0,output_size.width,output_size.height}; 24 | 25 | auto batch_size_in = image->get_size(0)* image->get_size(1); 26 | auto batch_size_out = result_size[0]*result_size[1]; 27 | for (auto i = 0u; i < image->get_size(2); i++) { 28 | 29 | auto status = nppiResize_32f_C1R((Npp32f *) (image->get_data_ptr() + i * batch_size_in), 30 | image->get_size(0) * sizeof(float),size, roi, 31 | (Npp32f *) (result.get_data_ptr() + i * batch_size_out), 32 | result_size[0] * sizeof(float), output_size, output_roi, NPPI_INTER_LINEAR); 33 | } 34 | 35 | return result; 36 | } -------------------------------------------------------------------------------- /xray/projection_utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by dch on 19/12/16. 3 | // 4 | #pragma once 5 | #ifndef GT_TOMOGRAPHY_PROJECTION_DOWNSAMPLER_H_H 6 | #define GT_TOMOGRAPHY_PROJECTION_DOWNSAMPLER_H_H 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace Gadgetron { 13 | 14 | cuNDArray downsample_projections(cuNDArray *image, float factorX, float factorY); 15 | 16 | } 17 | #endif //GT_TOMOGRAPHY_PROJECTION_DOWNSAMPLER_H_H 18 | 19 | 20 | --------------------------------------------------------------------------------