Skip to content

Commit

Permalink
Added wrapper sources
Browse files Browse the repository at this point in the history
  • Loading branch information
jbobin committed Apr 16, 2018
1 parent 0b89c3d commit ae44b37
Show file tree
Hide file tree
Showing 17 changed files with 1,039 additions and 1 deletion.
Binary file modified .DS_Store
Binary file not shown.
13 changes: 12 additions & 1 deletion README.md
Expand Up @@ -65,10 +65,21 @@ where the term O stands for sparse outliers. For more details, we refer the inte

***

### Third-party code : Undecimated wavelets with the pyredwave toolbox
### Third-party code :

* Undecimated wavelets with the pyredwave toolbox

The algorithms using sparsity in a transformed domain need the pyredwave Toolbox: a specific toolbox computing 1D or 2D wavelet transform on any 1 or 2 dimensions of an up to 4 dimensional data. Execute ”python setup.py build” in a terminal from the pyredwave folder so as to build it. The compilation requires Boost.Python (tested on Mac and Ubuntu, with Python 2.7). The toolbox uses OMP for CPU parallelization. To disable parallelization, remove the tag ” PARALLELIZED ” in pyredwave/pyredwave/cxx/redWaveTools.hpp

* cxxStarlet

The folder cxxStarlet contains C/python wrappers to compute the starlet transform (tested on Mac and Ubuntu, with Python 2.7). The toolbox uses OMP for CPU parallelization.
compilation is done as follows:
- Edit the CMakeList file and comment the desired command line (For MAC or For Linux) depending on the computer type
- Go to the build subfolder and type cmake .. (please note that cmake is required)
- If some libraries are missing (e.g. gsl, cfitsio, boost), you'll be notified to set them up
- Type make, this will yield a sparse2d.so file that you will be able to import in python

### Acknowledgement
Contributors include: J.Bobin, C.Chenot, C.Kervazo, J.Rapin.
Part of this work was funded European Community through the grant [LENA](http://lena.cosmostat.org) (ERC StG no. 678282) within the H2020 Framework Program.
Binary file added cxxStarlet/.DS_Store
Binary file not shown.
58 changes: 58 additions & 0 deletions cxxStarlet/CMakeLists.txt
@@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 2.8)

include(ExternalProject)
include(FindPkgConfig)

# Adding customized cmake module
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/")

project(sparse2d)

# Find required packages
find_package(Boost REQUIRED COMPONENTS python)
find_package(PythonInterp REQUIRED)
find_package(PythonLibsNew REQUIRED)

pkg_check_modules(GSL REQUIRED gsl)
pkg_check_modules(CFITSIO REQUIRED cfitsio)


# Downloads and compiles the Boost.NumPy package
# The library and include files are located in the build/extern directory
ExternalProject_Add(BoostNumpy
GIT_REPOSITORY https://github.com/ndarray/Boost.NumPy
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/extern
-DLIBRARY_TYPE=STATIC
)
set(BoostNumpy_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extern/include)
set(BoostNumpy_LIBRARY_DIRS ${CMAKE_BINARY_DIR}/extern/lib64)
set(BoostNumpy_LIBRARIES -lboost_numpy)


# Define include and library directories
include_directories(
${GSL_INCLUDE_DIRS}
${PYTHON_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${BoostNumpy_INCLUDE_DIRS}
${CFITSIO_INCLUDE_DIRS}
)
link_directories(${BoostNumpy_LIBRARY_DIRS} ${GSL_LIBRARY_DIRS} ${CFITSIO_LIBRARY_DIRS})

# Compilation flags
#if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang, disabling OpenMP support
# set(CMAKE_CXX_FLAGS "-O3 -fomit-frame-pointer -fno-common -fPIC")
#else()
# set(CMAKE_CXX_FLAGS "-O3 -fomit-frame-pointer -fno-common -fPIC -fopenmp")
#endif()

set(CMAKE_CXX_FLAGS "-O3 -fomit-frame-pointer -fno-common -fPIC -fopenmp -DRW_PYTHON_INTERFACE -F/Library/Frameworks -arch x86_64") # For MAC
#set(CMAKE_CXX_FLAGS "-O3 -fomit-frame-pointer -fno-common -fPIC -fopenmp -DRW_PYTHON_INTERFACE") # For Linux

# Build the tools module
add_library(sparse2d SHARED sparse2d/cxx/sparse2d.cpp sparse2d/cxx/starlet2d.cpp)
add_dependencies(sparse2d BoostNumpy)
target_link_libraries(sparse2d ${BoostNumpy_LIBRARIES} ${Boost_LIBRARIES} ${GSL_LIBRARIES} ${PYTHON_LIBRARIES})
set_target_properties(sparse2d PROPERTIES SUFFIX .so)
set_target_properties(sparse2d PROPERTIES PREFIX "")
Binary file added cxxStarlet/build/.DS_Store
Binary file not shown.
Binary file added cxxStarlet/cmake/.DS_Store
Binary file not shown.
211 changes: 211 additions & 0 deletions cxxStarlet/cmake/Modules/FindPythonLibsNew.cmake
@@ -0,0 +1,211 @@
# - Find python libraries
# This module finds the libraries corresponding to the Python interpeter
# FindPythonInterp provides.
# This code sets the following variables:
#
# PYTHONLIBS_FOUND - have the Python libs been found
# PYTHON_PREFIX - path to the Python installation
# PYTHON_LIBRARIES - path to the python library
# PYTHON_INCLUDE_DIRS - path to where Python.h is found
# PYTHON_SITE_PACKAGES - path to installation site-packages
# PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
#
# PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated)
#
# A function PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is defined to build modules for python.

#=============================================================================
# Copyright 2001-2009 Kitware, Inc.
# Copyright 2012 Continuum Analytics, Inc.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)

# Use the Python interpreter to find the libs.
if(PythonLibsNew_FIND_REQUIRED)
find_package(PythonInterp REQUIRED)
else()
find_package(PythonInterp)
endif()

if(NOT PYTHONINTERP_FOUND)
set(PYTHONLIBS_FOUND FALSE)
return()
endif()

# According to http://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
# testing whether sys has the gettotalrefcount function is a reliable, cross-platform
# way to detect a CPython debug interpreter.
execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
"from distutils import sysconfig as s;import sys;import struct;
print('.'.join(str(v) for v in sys.version_info));
print(s.PREFIX);
print(s.get_python_inc(plat_specific=True));
print(s.get_python_lib(plat_specific=True));
print(s.get_config_var('SO'));
print(hasattr(sys, 'gettotalrefcount')+0);
print(struct.calcsize('@P'));
"
RESULT_VARIABLE _PYTHON_SUCCESS
OUTPUT_VARIABLE _PYTHON_VALUES
ERROR_VARIABLE _PYTHON_ERROR_VALUE
OUTPUT_STRIP_TRAILING_WHITESPACE)

if(NOT _PYTHON_SUCCESS MATCHES 0)
if(PythonLibsNew_FIND_REQUIRED)
message(FATAL_ERROR
"Python config failure:\n${_PYTHON_ERROR_VALUE}")
endif()
set(PYTHONLIBS_FOUND FALSE)
return()
endif()

# Convert the process output into a list
string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
list(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
list(GET _PYTHON_VALUES 1 PYTHON_PREFIX)
list(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
list(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
list(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
list(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)
list(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)

# Make sure the Python has the same pointer-size as the chosen compiler
if(NOT ${PYTHON_SIZEOF_VOID_P} MATCHES ${CMAKE_SIZEOF_VOID_P})
if(PythonLibsNew_FIND_REQUIRED)
math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8")
math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
message(FATAL_ERROR
"Python config failure: Python is ${_PYTHON_BITS}-bit, "
"chosen compiler is ${_CMAKE_BITS}-bit")
endif()
set(PYTHONLIBS_FOUND FALSE)
return()
endif()

# The built-in FindPython didn't always give the version numbers
string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})
list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)
list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)

# Make sure all directory separators are '/'
string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX ${PYTHON_PREFIX})
string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR ${PYTHON_INCLUDE_DIR})
string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES ${PYTHON_SITE_PACKAGES})

# TODO: All the nuances of CPython debug builds have not been dealt with/tested.
if(PYTHON_IS_DEBUG)
set(PYTHON_MODULE_EXTENSION "_d${PYTHON_MODULE_EXTENSION}")
endif()

if(CMAKE_HOST_WIN32)
set(PYTHON_LIBRARY
"${PYTHON_PREFIX}/libs/Python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}.lib")
elseif(APPLE)
set(PYTHON_LIBRARY
"${PYTHON_PREFIX}/lib/libpython${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.dylib")
else()
if(${PYTHON_SIZEOF_VOID_P} MATCHES 8)
set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib64" "${PYTHON_PREFIX}/lib")
else()
set(_PYTHON_LIBS_SEARCH "${PYTHON_PREFIX}/lib")
endif()
# Probably this needs to be more involved. It would be nice if the config
# information the python interpreter itself gave us were more complete.
find_library(PYTHON_LIBRARY
NAMES "python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}"
PATHS ${_PYTHON_LIBS_SEARCH}
NO_SYSTEM_ENVIRONMENT_PATH)
endif()

# For backward compatibility, set PYTHON_INCLUDE_PATH, but make it internal.
SET(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}" CACHE INTERNAL
"Path to where Python.h is found (deprecated)")

MARK_AS_ADVANCED(
PYTHON_LIBRARY
PYTHON_INCLUDE_DIR
)

# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
# cache entries because they are meant to specify the location of a single
# library. We now set the variables listed by the documentation for this
# module.
SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")


# Don't know how to get to this directory, just doing something simple :P
#INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
#FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs DEFAULT_MSG PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS)
find_package_message(PYTHON
"Found PythonLibs: ${PYTHON_LIBRARY}"
"${PYTHON_EXECUTABLE}${PYTHON_VERSION}")


# PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is used to build modules for python.
FUNCTION(PYTHON_ADD_MODULE _NAME )
GET_PROPERTY(_TARGET_SUPPORTS_SHARED_LIBS
GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
OPTION(PYTHON_ENABLE_MODULE_${_NAME} "Add module ${_NAME}" TRUE)
OPTION(PYTHON_MODULE_${_NAME}_BUILD_SHARED
"Add module ${_NAME} shared" ${_TARGET_SUPPORTS_SHARED_LIBS})

# Mark these options as advanced
MARK_AS_ADVANCED(PYTHON_ENABLE_MODULE_${_NAME}
PYTHON_MODULE_${_NAME}_BUILD_SHARED)

IF(PYTHON_ENABLE_MODULE_${_NAME})
IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
SET(PY_MODULE_TYPE MODULE)
ELSE(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
SET(PY_MODULE_TYPE STATIC)
SET_PROPERTY(GLOBAL APPEND PROPERTY PY_STATIC_MODULES_LIST ${_NAME})
ENDIF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)

SET_PROPERTY(GLOBAL APPEND PROPERTY PY_MODULES_LIST ${_NAME})
ADD_LIBRARY(${_NAME} ${PY_MODULE_TYPE} ${ARGN})
TARGET_LINK_LIBRARIES(${_NAME} ${PYTHON_LIBRARIES})

IF(PYTHON_MODULE_${_NAME}_BUILD_SHARED)
SET_TARGET_PROPERTIES(${_NAME} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
SET_TARGET_PROPERTIES(${_NAME} PROPERTIES SUFFIX "${PYTHON_MODULE_EXTENSION}")
ELSE()
ENDIF()

ENDIF(PYTHON_ENABLE_MODULE_${_NAME})
ENDFUNCTION(PYTHON_ADD_MODULE)

Binary file added cxxStarlet/module/.DS_Store
Binary file not shown.
48 changes: 48 additions & 0 deletions cxxStarlet/module/pyStarlet.py
@@ -0,0 +1,48 @@

import sparse2d as sp2
import numpy as np

# pyStarlet

def forward(X,h = [0.0625,0.25,0.375,0.25,0.0625],J = 1):

nX = np.shape(X)
Lh = np.size(h)

W = sp2.Starlet2D(nX[1],nX[2],nX[0],J,Lh).forward_omp(np.real(X),np.array(h))

return W


def backward(W,h = [0.0625,0.25,0.375,0.25,0.0625]):

nX = np.shape(W)
Lh = np.size(h)

rec = sp2.Starlet2D(nX[1],nX[2],nX[0],nX[3]-1,Lh).backward_omp(np.real(W))

return rec

def forward1d(X,h = [0.0625,0.25,0.375,0.25,0.0625],J = 1):

nX = np.shape(X)
Lh = np.size(h)

W = sp2.Starlet2D(nX[1],1,nX[0],J,Lh).forward1d_omp(np.real(X),np.array(h))

return W

def adjoint1d(W,h = [0.0625,0.25,0.375,0.25,0.0625]):

nX = np.shape(W)
Lh = np.size(h)

W = sp2.Starlet2D(nX[1],1,nX[0],nX[2]-1,Lh).adjoint1d(np.real(W),np.array(h))

return W

def backward1d(W,h = [0.0625,0.25,0.375,0.25,0.0625]):

rec = np.sum(W,axis=2)

return rec
Binary file added cxxStarlet/module/pyStarlet.pyc
Binary file not shown.
Binary file added cxxStarlet/module/sparse2d.so
Binary file not shown.
Binary file added cxxStarlet/sparse2d/.DS_Store
Binary file not shown.
Binary file added cxxStarlet/sparse2d/cxx/.DS_Store
Binary file not shown.

0 comments on commit ae44b37

Please sign in to comment.