Skip to content

Commit 6787109

Browse files
authored
Merge pull request #90 from cheesema/develop
Develop
2 parents 1ba808f + 3c57e50 commit 6787109

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3786
-315
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ install:
2828
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install swig gnupg2 hdf5; fi
2929
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then /usr/libexec/java_home -V; fi
3030
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then echo "UPDATESTARTUPTTY" | gpg-connect-agent > /dev/null 2>&1; fi
31+
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake || brew upgrade cmake ; fi
3132
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then alias swig="swig3.0"; fi
3233
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export COMPILER=clang++-3.6; fi
3334
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXX=clang++-3.6; fi

CMakeLists.txt

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
###############################################################################
22
# APR - Adaptive Particle Representation
33
###############################################################################
4-
cmake_minimum_required(VERSION 3.2)
5-
project(LibAPR)
4+
cmake_minimum_required(VERSION 3.9)
5+
project(LibAPR DESCRIPTION "Adaptive Particle Representation library")
66

77
set(CMAKE_CXX_STANDARD 14)
8+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
89

910
# APR build options:
10-
option(APR_INSTALL "Install APR library" ON)
11+
option(APR_INSTALL "Install APR library" OFF)
1112
option(APR_BUILD_SHARED_LIB "Builds shared library" ON)
12-
option(APR_BUILD_STATIC_LIB "Builds shared library" ON)
13+
option(APR_BUILD_STATIC_LIB "Builds static library" OFF)
1314
option(APR_BUILD_EXAMPLES "Build APR examples" OFF)
1415
option(APR_TESTS "Build APR tests" OFF)
1516
option(APR_PREFER_EXTERNAL_GTEST "When found, use the installed GTEST libs instead of included sources" OFF)
1617
option(APR_PREFER_EXTERNAL_BLOSC "When found, use the installed BLOSC libs instead of included sources" OFF)
1718
option(APR_BUILD_JAVA_WRAPPERS "Build APR JAVA wrappers" OFF)
19+
option(APR_USE_CUDA "should APR use CUDA? (experimental - under development)" OFF)
20+
option(APR_BENCHMARK "add benchmarking code" OFF)
1821

1922
# Validation of options
2023
if (NOT APR_BUILD_SHARED_LIB AND NOT APR_BUILD_STATIC_LIB)
@@ -106,44 +109,73 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
106109
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
107110
endif()
108111

112+
if (APR_BENCHMARK)
113+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAPR_BENCHMARK")
114+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAPR_BENCHMARK")
115+
endif()
116+
109117

110118
###############################################################################
111119
# Generate APR library
112120
###############################################################################
113121

114122
set(LIBRARY_NAME apr)
115123

124+
include_directories(src)
125+
116126
set(SOURCE_FILES src/io/blosc_filter.c src/io/hdf5functions_blosc.cpp)
117127
set(SOURCE_FILES_RAYCAST src/numerics/APRRaycaster.cpp src/vis/Camera.cpp src/vis/Object.cpp src/vis/RaytracedObject.cpp)
118128

119129
add_library(aprObjLib OBJECT ${SOURCE_FILES} ${SOURCE_FILES_RAYCAST})
120130

131+
if(APR_USE_CUDA)
132+
message(STATUS "APR: Building CUDA for APR")
133+
set(CMAKE_CUDA_STANDARD 14)
134+
set(CMAKE_CUDA_FLAGS "--cudart shared -g -lineinfo -Xptxas -O3,-v -use_fast_math -DAPR_USE_CUDA")
135+
if(APR_BENCHMARK)
136+
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -DAPR_BENCHMARK")
137+
endif()
138+
enable_language(CUDA)
139+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DAPR_USE_CUDA")
140+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAPR_USE_CUDA")
141+
set(APR_CUDA_SROUCE_FILES
142+
src/algorithm/ComputeGradientCuda.cu
143+
src/algorithm/ComputeBsplineRecursiveFilter.cu
144+
src/algorithm/ComputeInverseCubicBsplineCuda.cu
145+
src/data_structures/Mesh/PixelData.cu
146+
src/algorithm/LocalIntensityScale.cu)
147+
include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
148+
endif()
149+
121150
if(APR_BUILD_STATIC_LIB)
122151
# generate static library used as a intermediate step in generating fat lib
123152
set(STATIC_TARGET_NAME staticLib)
124-
add_library(${STATIC_TARGET_NAME} STATIC $<TARGET_OBJECTS:aprObjLib>)
153+
add_library(${STATIC_TARGET_NAME} STATIC $<TARGET_OBJECTS:aprObjLib> ${APR_CUDA_SROUCE_FILES})
154+
target_compile_features(${STATIC_TARGET_NAME} PUBLIC cxx_std_14)
125155
set_target_properties(${STATIC_TARGET_NAME} PROPERTIES OUTPUT_NAME ${LIBRARY_NAME})
156+
set_target_properties(${STATIC_TARGET_NAME} PROPERTIES CUDA_SEPARABLE_COMPILATION OFF)
126157
target_include_directories(${STATIC_TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>)
127158

128159
# generate fat static library by adding dependencies
129-
include(cmake/AddStaticLibs.cmake)
130160
if(NOT BLOSC_FOUND)
161+
include(cmake/AddStaticLibs.cmake)
131162
addStaticLibs(${STATIC_TARGET_NAME} blosc_static)
132163
endif()
133164
endif()
134165

135166
if(APR_BUILD_SHARED_LIB)
136167
# generate fat shared library
137168
set(SHARED_TARGET_NAME sharedLib)
138-
add_library(${SHARED_TARGET_NAME} SHARED $<TARGET_OBJECTS:aprObjLib>)
169+
add_library(${SHARED_TARGET_NAME} SHARED $<TARGET_OBJECTS:aprObjLib> ${APR_CUDA_SROUCE_FILES})
170+
139171
target_include_directories(${SHARED_TARGET_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>)
140172
set_target_properties(${SHARED_TARGET_NAME} PROPERTIES OUTPUT_NAME ${LIBRARY_NAME})
141173
set_target_properties(${SHARED_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_NAME ${LIBRARY_NAME})
142174
set_target_properties(${SHARED_TARGET_NAME} PROPERTIES ARCHIVE_OUTPUT_NAME ${LIBRARY_NAME})
143175
set_property(TARGET ${SHARED_TARGET_NAME} PROPERTY VERSION ${APR_VERSION_STRING})
144176
set_property(TARGET ${SHARED_TARGET_NAME} PROPERTY SOVERSION ${APR_VERSION_MAJOR})
145177

146-
target_link_libraries(${SHARED_TARGET_NAME} PRIVATE ${HDF5_LIBRARIES} ${TIFF_LIBRARIES})
178+
target_link_libraries(${SHARED_TARGET_NAME} PRIVATE ${HDF5_LIBRARIES} ${TIFF_LIBRARIES} ${CUDA_CUDART_LIBRARY})
147179
if(BLOSC_FOUND)
148180
target_link_libraries(${SHARED_TARGET_NAME} PRIVATE ${BLOSC_LIBRARIES} ${ZLIB_LIBRARIES})
149181
else()
@@ -163,7 +195,6 @@ else()
163195
set(APR_BUILD_LIBRARY ${STATIC_TARGET_NAME})
164196
endif()
165197

166-
167198
###############################################################################
168199
# Install APR library
169200
###############################################################################
@@ -216,17 +247,14 @@ endif(APR_INSTALL)
216247
# Examples
217248
###############################################################################
218249
if(APR_BUILD_EXAMPLES)
219-
include_directories(src)
220250
message(STATUS "APR: Building examples")
221251
add_subdirectory(examples)
222252
endif(APR_BUILD_EXAMPLES)
223253

224-
225254
###############################################################################
226255
# Tests
227256
###############################################################################
228257
if(APR_TESTS)
229-
include_directories(src)
230258
message(STATUS "APR: Building tests")
231259
if(APR_PREFER_EXTERNAL_GTEST)
232260
find_package(GTest 1.8.0)

README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# LibAPR - The Adaptive Particle Representation Library
22

3-
Library for producing and processing on the Adaptive Particle Representation (APR) (For article see: https://www.biorxiv.org/content/early/2018/02/09/263061).
3+
Library for producing and processing on the Adaptive Particle Representation (APR) (For article see: https://www.biorxiv.org/content/early/2018/03/02/263061).
44

55
<img src="./docs/apr_lowfps_lossy.gif?raw=true">
66

@@ -16,10 +16,6 @@ Labeled Zebrafish nuclei: Gopi Shah, Huisken Lab ([MPI-CBG](https://www.mpi-cbg.
1616
* LibTIFF 5.0 or higher
1717
* SWIG 3.0.12 (optional, for generating Java wrappers)
1818

19-
Opening hdf5 files in ParaView or HDFView requires additional installation of two libraries:
20-
* c-blosc 1.11.2 or higher
21-
* hdf5-blosc 1.1.0 or higher
22-
2319
## Building
2420

2521
The repository requires sub-modules, so the repository needs to be cloned recursively:
@@ -58,7 +54,7 @@ We provide working Dockerfile that install the library within the image on a sep
5854

5955
On OSX, install the `cmake`, `hdf5` and `libtiff` [homebrew](https://brew.sh) packages and have the [Xcode command line tools](http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/) installed.
6056

61-
If you want to compile with OpenMP support, also install the `llvm` package, as the clang version shipped by Apple currently does not support OpenMP.
57+
If you want to compile with OpenMP support, also install the `llvm` package (this can also be done using homebrew), as the clang version shipped by Apple currently does not support OpenMP.
6258

6359
In the directory of the cloned repository, run
6460

@@ -71,7 +67,7 @@ make
7167

7268
This will create the `libapr.so` library in the `build` directory, as well as all of the examples.
7369

74-
In case you want to use the homebrew-installed clang, modify the call to `cmake` above to
70+
In case you want to use the homebrew-installed clang (OpenMP support), modify the call to `cmake` above to
7571

7672
```
7773
CC="/usr/local/opt/llvm/bin/clang" CXX="/usr/local/opt/llvm/bin/clang++" LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" CPPFLAGS="-I/usr/local/opt/llvm/include" cmake ..
@@ -102,24 +98,34 @@ There are nine basic examples, that show how to generate and compute with the AP
10298

10399
| Example | How to ... |
104100
|:--|:--|
105-
| [Example_get_apr](./examples/Example_get_apr.cpp) | create an APR file from a TIFF. |
106-
| [Example_apr_iterate](./examples/Example_apr_iterate.cpp) | iterate through a given APR file. |
101+
| [Example_get_apr](./examples/Example_get_apr.cpp) | create an APR from a TIFF and store as hdf5. |
102+
| [Example_apr_iterate](./examples/Example_apr_iterate.cpp) | iterate through a given APR. |
107103
| [Example_neighbour_access](./examples/Example_neighbour_access.cpp) | access particle and face neighbours. |
108-
| [Example_compress_apr](./examples/Example_compress_apr.cpp) | additionally compress the intensities stored in an APR file. |
109-
| [Example_compute_gradient](./examples/Example_compute_gradient.cpp) | compute a gradient based on the stored particles in an APR file. |
110-
| [Example_produce_paraview_file](./examples/Example_produce_paraview_file.cpp) | produce a file for visualisation in ParaView. |
104+
| [Example_compress_apr](./examples/Example_compress_apr.cpp) | additionally compress the intensities stored in an APR. |
105+
| [Example_compute_gradient](./examples/Example_compute_gradient.cpp) | compute a gradient based on the stored particles in an APR. |
106+
| [Example_produce_paraview_file](./examples/Example_produce_paraview_file.cpp) | produce a file for visualisation in ParaView or reading in Matlab. |
111107
| [Example_random_access](./examples/Example_random_access.cpp) | perform random access operations on particles. |
112-
| [Example_ray_cast](./examples/Example_ray_cast.cpp) | perform a maximum intensity projection ray cast directly on the APR data structures read from an APR file. |
113-
| [Example_reconstruct_image](./examples/Example_reconstruct_image.cpp) | reconstruct an pixel image from an APR file. |
108+
| [Example_ray_cast](./examples/Example_ray_cast.cpp) | perform a maximum intensity projection ray cast directly on the APR data structures read from an APR. |
109+
| [Example_reconstruct_image](./examples/Example_reconstruct_image.cpp) | reconstruct a pixel image from an APR. |
110+
111+
All examples except Example_get_apr require an already produced APR, such as those created by Example_get_apr.
114112

115113
For tutorial on how to use the examples, and explanation of data-structures see [the library guide](./docs/lib_guide.pdf).
116114

117115
## Coming soon
118116

119117
* more examples for APR-based filtering and segmentation
120-
* more convenient use from CMake projects
121118
* deployment of the Java wrappers to Maven Central so they can be used in your project directly
122119
* support for loading the APR in [Fiji](https://fiji.sc), including [scenery-based](https://github.com/scenerygraphics/scenery) 3D rendering
120+
* basic python wrapper support
121+
* improved java wrapper support
122+
* CUDA GPU-accelerated APR generation and processing
123+
124+
## Contact us
125+
126+
If anything is not working as you think it should, or would like it to, please get in touch with us!! Further, if you have a project, or algorithm, you would like to try using the APR for also please get in contact we would be glad to help!
127+
128+
[![Join the chat at https://gitter.im/LibAPR](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/LibAPR/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
123129

124130
## Citing this work
125131

examples/Example_compress_apr.cpp

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ Example_compress_apr -i input_image_tiff -d input_directory
1414
1515
Optional:
1616
17-
-compress_type number (1 or 2) (1 - WNL compression (Default), 2 - prediction step with lossless, potential rounding error)
17+
-compress_type number (1 or 2) (1 - WNL compression, only variance stabalization step (Default), 2 - variance stabalization and x,y,z prediction (note slower for ~30% compression gain)
1818
-quantization_level (Default 1: higher increasing the loss nature of the WNL compression aproach)
19+
-compress_level (the IO uses BLOSC for lossless compression of the APR, this can be set from 1-9, where higher increases the compression level. Note, this can come at a significant time increase.)
1920
20-
e.g. Example_compress_apr -i nuc_apr.h5 -d /Test/Input_examples/ -compress_type 2
21+
e.g. Example_compress_apr -i nuc_apr.h5 -d /Test/Input_examples/ -compress_type 1
2122
2223
Note: fine grained parameters can be tuned within the file, to play with lossless compression level, method used, and other parameters.
2324
@@ -59,17 +60,47 @@ int main(int argc, char **argv) {
5960
APRCompress<uint16_t> comp;
6061
ExtraParticleData<uint16_t> symbols;
6162

63+
//feel free to change
64+
unsigned int blosc_comp_type = BLOSC_ZSTD;
65+
unsigned int blosc_comp_level = options.compress_level;
66+
unsigned int blosc_shuffle = 1;
67+
6268
comp.set_quantization_factor(options.quantization_level); //set this to adjust the compression factor for WNL
6369
comp.set_compression_type(options.compress_type);
6470

65-
timer.start_timer("compress");
66-
apr.write_apr(options.directory ,name + "_compress",comp,BLOSC_ZSTD,1,2);
71+
//compress the APR and write to disk
72+
timer.start_timer("compress and write");
73+
FileSizeInfo fileSizeInfo = apr.write_apr(options.directory ,name + "_compress",comp,blosc_comp_type,blosc_comp_level,blosc_shuffle);
6774
timer.stop_timer();
6875

69-
timer.start_timer("decompress");
76+
float time_write = (float) timer.timings.back();
77+
78+
//read the APR and decompress
79+
timer.start_timer("read and decompress");
7080
apr.read_apr(options.directory + name + "_compress_apr.h5");
7181
timer.stop_timer();
7282

83+
float time_read = (float) timer.timings.back();
84+
85+
float original_pixel_image_size = (2.0f*apr.orginal_dimensions(0)*apr.orginal_dimensions(1)*apr.orginal_dimensions(2))/(1000000.0);
86+
std::cout << std::endl;
87+
std::cout << std::endl;
88+
std::cout << "Original image size: " << original_pixel_image_size << " MB" << std::endl;
89+
90+
float apr_compressed_file_size = fileSizeInfo.total_file_size;
91+
92+
std::cout << "Compressed (Lossy - WNL) APR: " << apr_compressed_file_size << " MB" << std::endl;
93+
std::cout << "Compression Ratio: " << original_pixel_image_size/apr_compressed_file_size << std::endl;
94+
std::cout << std::endl;
95+
std::cout << std::endl;
96+
97+
std::cout << "Effective Datarate Write (by original image size): " << original_pixel_image_size/time_write << " MB*/s" << std::endl;
98+
std::cout << "Effective Datarate Read (by original image size): " << original_pixel_image_size/time_read << " MB*/s" << std::endl;
99+
100+
std::cout << std::endl;
101+
std::cout << std::endl;
102+
103+
//writes the piece-wise constant reconstruction of the APR to file for comparison
73104
PixelData<uint16_t> img;
74105
apr.interp_img(img,apr.particles_intensities);
75106
std::string output = options.directory + name + "_compress.tif";
@@ -93,49 +124,53 @@ char* get_command_option(char **begin, char **end, const std::string &option)
93124
}
94125

95126

96-
cmdLineOptions read_command_line_options(int argc, char **argv){
127+
cmdLineOptions read_command_line_options(int argc, char **argv){
97128

98-
cmdLineOptions result;
129+
cmdLineOptions result;
99130

100-
if(argc == 1) {
101-
std::cerr << usage << std::endl;
102-
exit(1);
103-
}
131+
if(argc == 1) {
132+
std::cerr << usage << std::endl;
133+
exit(1);
134+
}
104135

105-
if(command_option_exists(argv, argv + argc, "-i"))
106-
{
107-
result.input = std::string(get_command_option(argv, argv + argc, "-i"));
108-
} else {
109-
std::cout << "Input file required" << std::endl;
110-
exit(2);
111-
}
136+
if(command_option_exists(argv, argv + argc, "-i"))
137+
{
138+
result.input = std::string(get_command_option(argv, argv + argc, "-i"));
139+
} else {
140+
std::cout << "Input file required" << std::endl;
141+
exit(2);
142+
}
112143

113-
if(command_option_exists(argv, argv + argc, "-d"))
114-
{
115-
result.directory = std::string(get_command_option(argv, argv + argc, "-d"));
116-
}
144+
if(command_option_exists(argv, argv + argc, "-d"))
145+
{
146+
result.directory = std::string(get_command_option(argv, argv + argc, "-d"));
147+
}
117148

118-
if(command_option_exists(argv, argv + argc, "-compress_type"))
119-
{
120-
result.compress_type = (unsigned int)std::stoi(std::string(get_command_option(argv, argv + argc, "-compress_type")));
121-
}
149+
if(command_option_exists(argv, argv + argc, "-compress_type"))
150+
{
151+
result.compress_type = (unsigned int)std::stoi(std::string(get_command_option(argv, argv + argc, "-compress_type")));
152+
}
122153

123-
if(result.compress_type > 2 || result.compress_type == 0){
154+
if(result.compress_type > 2 || result.compress_type == 0){
124155

125-
std::cerr << "Invalid Compression setting (1 or 2)" << std::endl;
126-
exit(1);
127-
}
156+
std::cerr << "Invalid Compression setting (1 or 2)" << std::endl;
157+
exit(1);
158+
}
128159

129160

130-
if(command_option_exists(argv, argv + argc, "-quantization_level"))
131-
{
132-
result.quantization_level =std::stof(std::string(get_command_option(argv, argv + argc, "-quantization_level")));
133-
}
161+
if(command_option_exists(argv, argv + argc, "-quantization_level"))
162+
{
163+
result.quantization_level =std::stof(std::string(get_command_option(argv, argv + argc, "-quantization_level")));
164+
}
134165

166+
if(command_option_exists(argv, argv + argc, "-compress_level"))
167+
{
168+
result.compress_level = (unsigned int)std::stoi(std::string(get_command_option(argv, argv + argc, "-compress_level")));
169+
}
135170

136171

137-
return result;
172+
return result;
138173

139-
}
174+
}
140175

141176

examples/Example_compress_apr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct cmdLineOptions{
1515
unsigned int compress_type=1;
1616
float quantization_level=1;
1717
bool stats_file = false;
18+
unsigned int compress_level = 2;
1819
};
1920

2021
cmdLineOptions read_command_line_options(int argc, char **argv);

0 commit comments

Comments
 (0)