Skip to content

Commit a0dbe0c

Browse files
committed
basic R support
1 parent b12b8c8 commit a0dbe0c

File tree

7 files changed

+214
-26
lines changed

7 files changed

+214
-26
lines changed

CMakeLists.txt

+1-4
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ include(CheckCompilerFeatures)
5252

5353
add_subdirectory(src/prostruct)
5454

55-
IF(ENABLE_INTERFACE)
56-
find_package(SWIG 3.0 REQUIRED)
57-
find_package(PythonLibs 3.6 REQUIRED)
58-
find_package(Numpy 1.7 REQUIRED)
55+
IF(${ENABLE_PYTHON} OR ${ENABLE_R})
5956
add_subdirectory(src/interface)
6057
ENDIF()
6158

README.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ C++:
2222
```cpp
2323
#include <prostruct/prostruct.h>
2424

25-
auto pdb = PDB<float>("test.pdb");
25+
auto pdb = PDB<float>("mypdb.pdb");
2626
auto ks = pdb.compute_kabsch_sander() // arma::Mat<float>
2727
```
2828

@@ -34,6 +34,16 @@ pdb = prostruct.PDB_float("mypdb.pdb")
3434
ks = pdb.compute_kabsch_sander() # numpy array
3535
```
3636

37+
R:
38+
```R
39+
dyn.load(paste("prostruct", .Platform$dynlib.ext, sep=""))
40+
source("prostruct.R")
41+
cacheMetaData(1)
42+
43+
pdb <- PDB_float("mypdb.pdb")
44+
ks = pdb$compute_kabsch_sander() # R matrix
45+
```
46+
3747
## Build with CMake
3848

3949
Currently ProStruct is only available from source.

cmake/FindR.cmake

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CMake module to find R
2+
# - Try to find R
3+
# Once done, this will define
4+
#
5+
# R_FOUND - system has R
6+
# R_INCLUDE_DIRS - the R include directories
7+
# R_LIBRARIES - link these to use R
8+
# R_ROOT_DIR - As reported by R
9+
# Autor: Omar Andres Zapata Mesa 31/05/2013
10+
11+
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
12+
set(CMAKE_FIND_APPBUNDLE "LAST")
13+
endif()
14+
15+
find_program(R_EXECUTABLE NAMES R R.exe)
16+
17+
#---searching R installtion unsing R executable
18+
if(R_EXECUTABLE)
19+
execute_process(COMMAND ${R_EXECUTABLE} RHOME
20+
OUTPUT_VARIABLE R_ROOT_DIR
21+
OUTPUT_STRIP_TRAILING_WHITESPACE)
22+
23+
find_path(R_INCLUDE_DIR R.h
24+
HINTS ${R_ROOT_DIR}
25+
PATHS /usr/local/lib /usr/local/lib64 /usr/share
26+
PATH_SUFFIXES include R/include
27+
DOC "Path to file R.h")
28+
29+
find_library(R_LIBRARY R
30+
HINTS ${R_ROOT_DIR}/lib
31+
DOC "R library (example libR.a, libR.dylib, etc.).")
32+
endif()
33+
34+
#---setting include dirs and libraries
35+
set(R_LIBRARIES ${R_LIBRARY})
36+
set(R_INCLUDE_DIRS ${R_INCLUDE_DIR})
37+
foreach(_cpt ${R_FIND_COMPONENTS})
38+
execute_process(COMMAND echo "cat(find.package('${_cpt}'))"
39+
COMMAND ${R_EXECUTABLE} --vanilla --slave
40+
RESULT_VARIABLE _rc
41+
ERROR_QUIET
42+
OUTPUT_VARIABLE _cpt_path
43+
OUTPUT_STRIP_TRAILING_WHITESPACE)
44+
if(NOT _rc)
45+
set(R_${_cpt}_FOUND 1)
46+
endif()
47+
48+
find_library(R_${_cpt}_LIBRARY
49+
lib${_cpt}.so lib${_cpt}.dylib
50+
HINTS ${_cpt_path}/lib)
51+
if(R_${_cpt}_LIBRARY)
52+
mark_as_advanced(R_${_cpt}_LIBRARY)
53+
list(APPEND R_LIBRARIES ${R_${_cpt}_LIBRARY})
54+
endif()
55+
56+
find_path(R_${_cpt}_INCLUDE_DIR ${_cpt}.h HINTS ${_cpt_path} PATH_SUFFIXES include R/include)
57+
if(R_${_cpt}_INCLUDE_DIR)
58+
mark_as_advanced(R_${_cpt}_INCLUDE_DIR)
59+
list(APPEND R_INCLUDE_DIRS ${R_${_cpt}_INCLUDE_DIR})
60+
endif()
61+
62+
endforeach()
63+
64+
# Handle the QUIETLY and REQUIRED arguments and set R_FOUND to TRUE if all listed variables are TRUE
65+
include(FindPackageHandleStandardArgs)
66+
find_package_handle_standard_args(R HANDLE_COMPONENTS REQUIRED_VARS R_EXECUTABLE R_INCLUDE_DIR R_LIBRARY)
67+
mark_as_advanced(R_FOUND R_EXECUTABLE R_INCLUDE_DIR R_LIBRARY)

src/interface/CMakeLists.txt

+53-15
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,67 @@
11
cmake_minimum_required(VERSION 3.13)
22

3-
set(TARGET_NAME prostruct_interface)
3+
find_package(SWIG 3.0 REQUIRED)
4+
5+
set(PYTHON_TARGET_NAME prostruct_python_interface)
6+
set(R_TARGET_NAME prostruct_r_interface)
7+
48
cmake_policy(SET CMP0078 NEW)
59

610
if(${CMAKE_VERSION} GREATER "3.14.0")
7-
cmake_policy(SET CMP0086 NEW)
11+
cmake_policy(SET CMP0086 OLD)
812
endif()
913

1014
include(${SWIG_USE_FILE})
1115
include_directories(swig)
1216
include_directories(${PROJECT_SOURCE_DIR}/src)
13-
file(GLOB_RECURSE SWIG_FILES ${PROJECT_SOURCE_DIR}/src/interface/python/*.i)
1417

15-
set_property(SOURCE ${SWIG_FILES} PROPERTY CPLUSPLUS ON)
1618
#set(CMAKE_SWIG_OUTDIR ${CMAKE_BINARY_DIR}/src/interface/python)
17-
set(CMAKE_SWIG_FLAGS "-builtin")
18-
swig_add_library(${TARGET_NAME}
19-
LANGUAGE python SOURCES ${SWIG_FILES})
20-
target_include_directories(${TARGET_NAME} PUBLIC ${PYTHON_INCLUDE_DIRS} PUBLIC ${PROJECT_SOURCE_DIR}/src)
19+
if (ENABLE_PYTHON)
20+
find_package(PythonLibs 3.6 REQUIRED)
21+
find_package(Numpy 1.7 REQUIRED)
22+
file(GLOB_RECURSE SWIG_FILES ${PROJECT_SOURCE_DIR}/src/interface/python/*.i)
23+
set_property(SOURCE ${SWIG_FILES} PROPERTY CPLUSPLUS ON)
2124

22-
if (APPLE)
23-
target_link_libraries(${TARGET_NAME} PUBLIC "-undefined dynamic_lookup")
25+
set(CMAKE_SWIG_FLAGS "-builtin")
26+
swig_add_library(${PYTHON_TARGET_NAME}
27+
LANGUAGE python SOURCES ${SWIG_FILES}
28+
OUTFILE_DIR "${CMAKE_BINARY_DIR}/src/interface/python"
29+
OUTPUT_DIR "${CMAKE_BINARY_DIR}/src/interface/python")
30+
target_include_directories(${PYTHON_TARGET_NAME}
31+
PUBLIC ${PYTHON_INCLUDE_DIRS}
32+
PUBLIC ${PROJECT_SOURCE_DIR}/src)
33+
if (APPLE)
34+
target_link_libraries(${PYTHON_TARGET_NAME} PUBLIC "-undefined dynamic_lookup")
35+
endif()
36+
target_link_libraries(${PYTHON_TARGET_NAME} PUBLIC prostruct ${ARMADILLO_LIBRARIES})
37+
target_include_directories(${PYTHON_TARGET_NAME} PUBLIC ${NUMPY_INCLUDE_DIRS})
38+
set_target_properties(${PYTHON_TARGET_NAME} PROPERTIES SWIG_DEPENDS prostruct)
39+
set_target_properties(${PYTHON_TARGET_NAME} PROPERTIES
40+
OUTPUT_NAME prostruct
41+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src/interface/python")
42+
endif()
43+
if (ENABLE_R)
44+
find_package(R REQUIRED)
45+
find_package(Rcpp REQUIRED)
46+
find_package(Boost REQUIRED)
47+
file(GLOB_RECURSE SWIG_FILES ${PROJECT_SOURCE_DIR}/src/interface/r/*.i)
48+
set_property(SOURCE ${SWIG_FILES} PROPERTY CPLUSPLUS ON)
49+
set(CMAKE_SWIG_FLAGS "")
50+
swig_add_library(${R_TARGET_NAME}
51+
LANGUAGE r SOURCES ${SWIG_FILES}
52+
OUTFILE_DIR "${CMAKE_BINARY_DIR}/src/interface/r"
53+
OUTPUT_DIR "${CMAKE_BINARY_DIR}/src/interface/r")
54+
target_include_directories(${R_TARGET_NAME}
55+
PUBLIC ${R_INCLUDE_DIR}
56+
PUBLIC ${RCPP_INCLUDE_DIR}
57+
PUBLIC ${PROJECT_SOURCE_DIR}/src
58+
PUBLIC ${Boost_INCLUDE_DIRS})
59+
if (APPLE)
60+
target_link_libraries(${R_TARGET_NAME} PUBLIC "-undefined dynamic_lookup")
61+
endif()
62+
target_link_libraries(${R_TARGET_NAME} PUBLIC prostruct ${ARMADILLO_LIBRARIES} ${R_LIBRARIES})
63+
set_target_properties(${R_TARGET_NAME} PROPERTIES SWIG_DEPENDS prostruct)
64+
set_target_properties(${R_TARGET_NAME} PROPERTIES
65+
OUTPUT_NAME prostruct
66+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src/interface/r")
2467
endif()
25-
26-
target_link_libraries(${TARGET_NAME} PUBLIC prostruct ${ARMADILLO_LIBRARIES})
27-
target_include_directories(${TARGET_NAME} PUBLIC ${NUMPY_INCLUDE_DIRS})
28-
set_target_properties(${TARGET_NAME} PROPERTIES SWIG_DEPENDS prostruct)
29-
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME prostruct)

src/interface/python/typemaps.i

-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
ARMA_COL_OUT(float, NPY_FLOAT);
3838
ARMA_COL_OUT(double, NPY_DOUBLE);
3939
ARMA_COL_OUT(arma::uword, NPY_ULONGLONG);
40-
ARMA_COL_OUT(unsigned long long, NPY_ULONGLONG);
41-
4240

4341
ARMA_MAT_OUT(float, NPY_FLOAT);
4442
ARMA_MAT_OUT(double, NPY_DOUBLE);

src/interface/r/typemaps.i

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
%{
2+
#include <boost/smart_ptr/shared_ptr.hpp>
3+
%}
4+
5+
6+
7+
%define ARMA_COL_OUT(TYPE, R_TYPESXP, R_CAST_TYPE, R_TYPE, R_TYPE_STRING)
8+
%typemap(out) arma::Col<TYPE>
9+
{
10+
Rf_protect($result = Rf_allocVector(R_TYPESXP, $1.size()));
11+
printf("TEST");
12+
fflush(stdout);
13+
for (arma::uword i=0; i< $1.size(); ++i)
14+
{
15+
R_TYPE($result)[i] = static_cast<R_CAST_TYPE>($1(i));
16+
}
17+
Rf_unprotect(1);
18+
}
19+
20+
%typemap("rtype") arma::Col<TYPE> R_TYPE_STRING
21+
22+
%typemap("scoerceout") arma::Col<TYPE>
23+
%{ %}
24+
25+
%enddef
26+
27+
%define ARMA_MAT_OUT(TYPE, R_TYPESXP, R_CAST_TYPE, R_TYPE)
28+
%typemap(out) arma::Mat<TYPE>
29+
{
30+
Rf_protect($result = Rf_allocMatrix(R_TYPESXP, $1.n_cols, $1.n_rows));
31+
for (arma::uword i=0; i < $1.n_rows; ++i)
32+
{
33+
for (arma::uword j=0; j < $1.n_cols; ++j)
34+
{
35+
R_TYPE($result)[i*$1.n_cols+j] = static_cast<R_CAST_TYPE>($1(i, j));
36+
}
37+
}
38+
Rf_unprotect(1);
39+
}
40+
41+
%typemap("rtype") arma::Mat<TYPE> "matrix"
42+
43+
%typemap("scoerceout") arma::Mat<TYPE>
44+
%{ %}
45+
46+
%enddef
47+
48+
ARMA_COL_OUT(float, REALSXP, float, REAL, "numeric");
49+
ARMA_COL_OUT(double, REALSXP, float, REAL, "numeric");
50+
ARMA_COL_OUT(arma::uword, INTSXP, int, INTEGER, "integer");
51+
52+
ARMA_MAT_OUT(float, REALSXP, float, REAL);
53+
ARMA_MAT_OUT(double, REALSXP, float, REAL);
54+
ARMA_MAT_OUT(arma::uword, INTSXP, int, INTEGER);
55+
56+
%include "prostruct.i"

src/interface/swig/prostruct.i

+26-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
$action
1111
} catch (const std::exception& e) {
1212
SWIG_exception(SWIG_RuntimeError, e.what());
13+
} catch (const char* e) {
14+
SWIG_exception(SWIG_RuntimeError, e);
1315
} catch (const std::string& e) {
1416
SWIG_exception(SWIG_RuntimeError, e.c_str());
1517
}
@@ -22,12 +24,32 @@
2224
%template() std::vector<std::string>;
2325
#endif
2426

27+
#ifdef SWIGPYTHON
2528
%include <std_shared_ptr.i>
29+
#else
30+
%include <boost_shared_ptr.i>
31+
#endif
32+
33+
//#ifdef SWIGPYTHON
34+
%define ADD_SHARED_PTR(class_name)
35+
%shared_ptr(class_name)
36+
%enddef
37+
// #else
38+
// %define ADD_SHARED_PTR(class_name)
39+
// %boost_shared_ptr(class_name)
40+
// %enddef
41+
// #endif
42+
43+
ADD_SHARED_PTR(prostruct::Residue<float>)
44+
ADD_SHARED_PTR(prostruct::Residue<double>)
45+
ADD_SHARED_PTR(prostruct::Chain<float>)
46+
ADD_SHARED_PTR(prostruct::Chain<double>)
47+
48+
//%shared_ptr(prostruct::Residue<float>)
49+
//%shared_ptr(prostruct::Residue<double>)
50+
//%shared_ptr(prostruct::Chain<float>)
51+
//%shared_ptr(prostruct::Chain<double>)
2652

27-
%shared_ptr(prostruct::Residue<float>)
28-
%shared_ptr(prostruct::Residue<double>)
29-
%shared_ptr(prostruct::Chain<float>)
30-
%shared_ptr(prostruct::Chain<double>)
3153
//%shared_ptr(prostruct::PDB)
3254

3355
%include "prostruct/pdb/PDB.h"

0 commit comments

Comments
 (0)