Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding unit test #16

Merged
merged 11 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .github/workflows/build_cmake.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
name: cmake build
name: build & test

on:
push:
branches: [ "main", "dev" ]
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch: # This is the manual trigger

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest

steps:
Expand All @@ -41,4 +39,8 @@ jobs:
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}


# Run Unit Tests
- name: Run Unit Tests
run: |
cd ${{github.workspace}}/build/tests
./spinwalk_test
69 changes: 49 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ cmake_minimum_required(VERSION 3.24)
message(STATUS "CMake version: ${CMAKE_VERSION}")
include(CheckLanguage)

set(project "SpinWalk")
project(${project})
set(project_exe "SpinWalk_exe")
set(project_lib "SpinWalk_lib")
project(${project_exe})

# Find HDF5
find_package(HDF5 REQUIRED COMPONENTS CXX)
Expand All @@ -15,7 +16,7 @@ find_package(TBB REQUIRED)
if(CMAKE_VERSION VERSION_GREATER "3.30")
cmake_policy(SET CMP0167 NEW)
endif()
find_package(Boost COMPONENTS log log_setup REQUIRED)
find_package(Boost REQUIRED COMPONENTS log log_setup)

check_language(CUDA)
# Check for CUDA-capable GPU
Expand All @@ -28,6 +29,8 @@ else()
message("CUDA not found. Compiling without GPU support.")
endif()

find_package(OpenMP)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_compile_definitions(MINI_CASE_SENSITIVE)
Expand All @@ -39,22 +42,21 @@ if(CMAKE_BUILD_TYPE MATCHES Debug)
endif()

# Add Boost and CUDA include directories
include_directories(${Boost_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS} ./include ./src ./src/shapes)
# Add subfolders
add_subdirectory(./src/dwi)
add_subdirectory(./src/phantom)
add_subdirectory(./src/config)
add_subdirectory(./src/sim)
include_directories(${Boost_INCLUDE_DIRS} ${HDF5_INCLUDE_DIRS} ./include ./src)
# Add modules directory
add_subdirectory(src/dwi)
add_subdirectory(src/phantom)
add_subdirectory(src/config)
add_subdirectory(src/sim)

# Add the executable
set(SOURCES ./src/spinwalk.cu ${SUBCOMMAND_PHANTOM} ${SUBCOMMAND_SIM} ${SUBCOMMAND_DWI} ${SUBCOMMAND_CONFIG})
# Add the sources files
set(SOURCE_MODULES ${SUBCOMMAND_PHANTOM} ${SUBCOMMAND_SIM} ${SUBCOMMAND_DWI} ${SUBCOMMAND_CONFIG})
set(SOURCE_MAIN ./src/spinwalk.cu)

if(CMAKE_CUDA_COMPILER)
add_executable(${project} ${SOURCES})
target_link_libraries(${project} ${CUDA_LIBRARIES} ${Boost_LIBRARIES} ${HDF5_CXX_LIBRARIES} TBB::tbb)
else()
# change extension of the files if CUDA is not found
if(NOT CMAKE_CUDA_COMPILER)
set(RENAMED_SOURCES)
foreach(OLD_FILE ${SOURCES})
foreach(OLD_FILE ${SOURCE_MODULES})
# Get the file name without extension
get_filename_component(DIR ${OLD_FILE} DIRECTORY)
get_filename_component(FILE_NAME_WE ${OLD_FILE} NAME_WE)
Expand All @@ -64,15 +66,42 @@ else()
file(COPY_FILE ${OLD_FILE} ${NEW_FILE})
list(APPEND RENAMED_SOURCES ${NEW_FILE})
endforeach()
add_executable(${project} ${RENAMED_SOURCES})
target_link_libraries(${project} ${Boost_LIBRARIES} ${HDF5_CXX_LIBRARIES} TBB::tbb)
set(SOURCE_MODULES ${RENAMED_SOURCES})

file(COPY_FILE ./src/spinwalk.cu ./src/spinwalk.cpp)
set(SOURCE_MAIN ./src/spinwalk.cpp)
endif()

set_target_properties(${project} PROPERTIES OUTPUT_NAME "spinwalk")
# Add the executable
add_library(${project_lib} ${SOURCE_MODULES})
add_executable(${project_exe} ${SOURCE_MAIN})

# Add the libraries
if(CMAKE_CUDA_COMPILER)
target_link_libraries(${project_lib} ${CUDA_LIBRARIES})
endif()
if(OpenMP_CXX_FOUND)
message(STATUS "Found OpenMP, adding to target link libraries.")
target_link_libraries(${project_lib} OpenMP::OpenMP_CXX)
else()
message(STATUS "OpenMP not found, skipping.")
endif()
target_link_libraries(${project_lib} ${Boost_LIBRARIES} ${HDF5_CXX_LIBRARIES} TBB::tbb)
target_link_libraries(${project_exe} PRIVATE ${project_lib})

# Set the output name
set_target_properties(${project_exe} PROPERTIES OUTPUT_NAME "spinwalk")
set_target_properties(${project_lib} PROPERTIES OUTPUT_NAME "spinwalk")


# Install the executable
if (UNIX)
install(TARGETS ${project} DESTINATION bin)
install(TARGETS ${project_exe} DESTINATION bin)
install(TARGETS ${project_lib} DESTINATION lib)
endif()

# Add the tests directory
add_subdirectory(tests)

# cmake ..
# cmake --build . --config Release
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
---
### Demo

Jupyter notebooks demonstrating the basic functionality of SpinWalk for [BOLD fMRI contrast](./demo/spinwalk_example.ipynb) and [free diffusion](./demo/spinwalk_dwi.ipynb) simulations can be found in the [demo](./demo) folder.
Jupyter notebooks demonstrating the basic functionality of SpinWalk for [BOLD fMRI contrast](./demo/spinwalk_bold.ipynb) and [free diffusion](./demo/spinwalk_dwi.ipynb) simulations can be found in the [demo](./demo) folder.

Below are example plots generated by SpinWalk, showing BOLD sensitivity as a function of vessel size for Gradient Echo (GRE) and Spin Echo (SE) sequences. Some [literature](#Literature) is provided as a reference to help understand the intended outcomes of these simulations.

Expand Down
3 changes: 2 additions & 1 deletion containers/Dockerfile_CPU
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ RUN rm -rf ./build && cmake -B ./build && cmake --build ./build --config Release
# Stage 2: Runtime
FROM ubuntu:24.04
USER root
RUN apt-get update && apt install -y libboost-log1.83.0 libtbb-dev libhdf5-103-1 --no-install-recommends && apt-get clean && apt-get -y autoremove && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt install -y libboost-log1.83.0 libtbb-dev libhdf5-103-1 libomp5 --no-install-recommends && apt-get clean && apt-get -y autoremove && rm -rf /var/lib/apt/lists/*
COPY --from=builder /opt/SpinWalk/build/spinwalk /usr/local/bin/
COPY --from=builder /opt/SpinWalk/build/tests/spinwalk_test /usr/local/bin/
LABEL org.opencontainers.image.authors="Ali Aghaeifar"

# docker run --rm -it -v /DATA2:/mnt/DATA2 spinwalk_cpu:ubuntu24.04 bash
1 change: 1 addition & 0 deletions containers/create_dockers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
pushd "$SCRIPT_DIR" > /dev/null

# docker system prune -a --volumes --force
docker system prune --force

CUDA_VERSIONS=("12.0.0" "12.2.0" "12.6.3")

Expand Down
105 changes: 53 additions & 52 deletions demo/spinwalk_example.ipynb → demo/spinwalk_bold.ipynb

Large diffs are not rendered by default.

144 changes: 74 additions & 70 deletions demo/spinwalk_dwi.ipynb

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define DEFINITIONS_H

#define VERSION_MAJOR 1
#define VERSION_MINOR 17
#define VERSION_MINOR 18
#define VERSION_PATCH 2

// Helper macros to stringify values
Expand All @@ -12,6 +12,7 @@
#define SPINWALK_VERSION STRINGIFY(VERSION_MAJOR) "." STRINGIFY(VERSION_MINOR) "." STRINGIFY(VERSION_PATCH)

#define ERR_MSG "\033[1;31mError:\033[0m "
#define WARN_MSG "\033[1;33mWarning:\033[0m "

// #define MINI_CASE_SENSITIVE

Expand Down
6 changes: 3 additions & 3 deletions src/phantom/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ namespace phantom {
if (args.cylinder){
std::cout << "Generating cylinder phantom..." << std::endl;
cylinder cyl(args.fov, args.resolution, args.dchi, args.oxy_level, args.radius, args.volume_fraction, args.orientation, args.seed, args.output);
status = status && cyl.run();
status = status && cyl.run(true);
}
if (args.sphere){
std::cout << "Generating sphere phantom..." << std::endl;
sphere sph(args.fov, args.resolution, args.dchi, args.oxy_level, args.radius, args.volume_fraction, args.seed,args.output);
status = status && sph.run();
status = status && sph.run(true);
}
std::cout << "Done." << std::endl;
return true;
return status;
}
}
10 changes: 5 additions & 5 deletions src/phantom/phantom_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ phantom_base::phantom_base()
m_fov = 0;
m_resolution = 0;
m_seed = std::random_device{}();
set_blood_parameters(0.273e-6 * 0.4, 0, 10.0);
set_parameters(0.273e-6 * 0.4, 0, 10.0);
set_filename();
}

phantom_base::phantom_base(float fov_um, size_t resolution, float dChi, float Y, float BVF, int32_t seed, std::string filename)
:phantom_base()
{
set_space(fov_um, resolution);
set_blood_parameters(dChi, Y, BVF);
set_parameters(dChi, Y, BVF);
set_filename(filename);
if(seed >= 0)
m_seed = seed;
Expand All @@ -47,11 +47,11 @@ void phantom_base::set_space(float fov_um, size_t resolution)
this->m_resolution = resolution;
}

void phantom_base::set_blood_parameters(float dChi, float Y, float BVF)
void phantom_base::set_parameters(float dChi, float Y, float volume_fraction)
{
this->m_dChi = dChi;
this->m_Y = Y;
this->m_BVF = BVF;
this->m_volume_fraction = volume_fraction;
m_calc_fieldmap = Y >= 0;
}

Expand Down Expand Up @@ -92,7 +92,7 @@ bool phantom_base::save() const
// blood volume fraction
std::vector<size_t> dims_1(1, 1);
HighFive::DataSet dataset_BVF = file.createDataSet<float>("bvf", HighFive::DataSpace(dims_1));
dataset_BVF.write_raw(&m_BVF);
dataset_BVF.write_raw(&m_volume_fraction);

return true;
}
Expand Down
9 changes: 5 additions & 4 deletions src/phantom/phantom_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@ class phantom_base
{
public:
phantom_base();
phantom_base(float fov_um, size_t resolution, float dChi, float Y, float BVF, int32_t seed, std::string filename);
phantom_base(float fov_um, size_t resolution, float dChi, float Y, float volume_fraction, int32_t seed, std::string filename);
virtual ~phantom_base();
void set_space(float fov_um, size_t resolution);
void set_blood_parameters(float dChi, float Y, float BVF = 10.0);
void set_parameters(float dChi, float Y, float volume_fraction = 10.0);
void set_filename(std::string filename = "shape.h5");
virtual bool run(){return true;};
virtual bool run(bool write_to_disk) = 0;
virtual bool save() const;
virtual bool create_grid();
virtual bool generate_shapes() = 0;
virtual bool generate_mask_fieldmap() = 0;
float get_actual_volume_fraction() const {return m_volume_fraction;}

friend std::ostream& operator<<(std::ostream& os, const phantom_base& obj);

Expand All @@ -44,7 +45,7 @@ class phantom_base
std::vector<int8_t> m_mask;
size_t m_resolution;
float m_fov, m_dChi, m_Y;
float m_BVF; // blood volume fraction
float m_volume_fraction; // volume fraction
std::string m_filename;
float B0[3] = {0.f, 0.f, 1.f};
bool m_calc_fieldmap;
Expand Down
Loading
Loading