Commit 1941cad5 authored by Thomas Purcell's avatar Thomas Purcell
Browse files

Update Documentation so Doxygen strings are moved into python docstrings

Use keyed files to automatically generate bindings.hpp/bindings.cpp
parent d19ff92d
function(transfer_doc_string PYTHON_BINDING_FILE PYTHON_BINDING_FILE_OUT)
file(READ ${PYTHON_BINDING_FILE} BINDINGS)
string(REGEX REPLACE "\n" ";" BINDINGS "${BINDINGS}")
string(REGEX MATCHALL "DocString_[A-Za-z0-9_]+" DOCSTRING_KEYS ${BINDINGS})
file(GLOB_RECURSE HEADER_FILES *.hpp)
file(GLOB_RECURSE NOT_HEADER_FILES *config.hpp)
list(REMOVE_ITEM HEADER_FILES ${NOT_HEADER_FILES})
foreach(HEADER_FILE ${HEADER_FILES})
# To find the line with the flag
file(READ ${HEADER_FILE} CONTENTS)
string(REGEX REPLACE "[ \t]*// DocString: " "// DocString: " CONTENTS ${CONTENTS})
string(REGEX REPLACE "[ \t]*/[*][*]" "/**" CONTENTS ${CONTENTS})
string(REGEX REPLACE "[ \t]* [*]" " *" CONTENTS ${CONTENTS})
string(REGEX REPLACE "[ \t]* [*]/" " [*]/" CONTENTS ${CONTENTS})
string(REGEX REPLACE "\n" ";" CONTENTS "${CONTENTS}")
foreach(KEY ${DOCSTRING_KEYS})
# Get key to search for inside the source file
string(REGEX REPLACE "DocString\\_" "// DocString: " HEADER_KEY ${KEY})
# string(REGEX REPLACE "\\)" "" HEADER_KEY ${HEADER_KEY})
# Remove tabs before DoxyGen Comments
list(FIND CONTENTS "${HEADER_KEY}" INDEX)
string(COMPARE NOTEQUAL ${INDEX} -1 CONDITION)
if(CONDITION)
unset(DOCSTRING)
unset(DOXY_COMMENTS)
# To extract doxygen comments
math(EXPR INDEX "${INDEX}+1")
list(GET CONTENTS ${INDEX} LINE)
if(${LINE} MATCHES "/[*][*]")
math(EXPR INDEX "${INDEX}+1")
list(GET CONTENTS ${INDEX} LINE)
endif()
while(${LINE} MATCHES "(.*)")
string(REGEX MATCH "@([a-z]+) (.*)" LINE "${LINE}")
set(DOXY_COMMENTS ${DOXY_COMMENTS} ${LINE})
math(EXPR INDEX "${INDEX}+1")
list(GET CONTENTS ${INDEX} LINE)
endwhile()
set(IN_PARAMS OFF)
# To convert doxygen comments into docstrings
foreach(LINE ${DOXY_COMMENTS})
string(REGEX REPLACE "@brief " "" LINE "${LINE}")
string(REGEX REPLACE "@details " "" LINE "${LINE}")
if("${LINE}" MATCHES "@param ([a-zA-Z0-9_]+) (.*)")
if(IN_PARAMS)
set(LINE " ${CMAKE_MATCH_1}: ${CMAKE_MATCH_2}")
else(NOT IN_PARAMS)
set(LINE "Args:\\n ${CMAKE_MATCH_1}: ${CMAKE_MATCH_2}")
set(IN_PARAMS ON)
endif()
endif()
if("${LINE}" MATCHES "@param ([a-zA-Z0-9_]+) (\\([a-zA-Z0-9_.]+\\)) (.*)")
if(IN_PARAMS)
set(LINE " ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}: ${CMAKE_MATCH_3}")
else(NOT IN_PARAMS)
set(LINE "Args:\\n ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}: ${CMAKE_MATCH_3}")
set(IN_PARAMS ON)
endif()
endif()
if("${LINE}" MATCHES "@param ([a-zA-Z0-9_]+)(\\([a-zA-Z0-9_.]+\\)) (.*)")
if(IN_PARAMS)
set(LINE " ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}: ${CMAKE_MATCH_3}")
else(NOT IN_PARAMS)
set(LINE "Args:\\n ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}: ${CMAKE_MATCH_3}")
set(IN_PARAMS ON)
endif()
endif()
if ("${LINE}" MATCHES "@return (.+)")
set(LINE "\\nReturns:\\n ${CMAKE_MATCH_1}")
endif()
set(DOCSTRING ${DOCSTRING} ${LINE})
endforeach()
string(REPLACE ";" "\\n" DOCSTRING "${DOCSTRING}")
set(${KEY} ${DOCSTRING})
endif()
endforeach()
endforeach()
# # To insert docstrings in cpp file
# set(Docstring_${FUNCTION} ${DOCSTRING})
configure_file(${PYTHON_BINDING_FILE} ${PYTHON_BINDING_FILE_OUT} @ONLY)
endfunction()
\ No newline at end of file
......@@ -30,8 +30,14 @@ target_link_libraries(sisso++ ${LAPACK_LIBRARIES} ${MPI_LIBRARIES} ${PYTHON_LIB
install(TARGETS sisso++ DESTINATION ${CMAKE_CURRENT_LIST_DIR}/../bin/)
if(USE_PYTHON)
include(${CMAKE_CURRENT_LIST_DIR}/../cmake/TransferDocStrings.cmake)
file(GLOB_RECURSE SISSOLIB_SOURCES *.cpp)
list(REMOVE_ITEM SISSOLIB_SOURCES main.cpp)
list(REMOVE_ITEM SISSOLIB_SOURCES ${CMAKE_CURRENT_LIST_DIR}/python/bindings_docstring_keyed.cpp)
list(REMOVE_ITEM SISSOLIB_SOURCES ${CMAKE_CURRENT_LIST_DIR}/python/bindings_docstring_keyed.hpp)
transfer_doc_string(${CMAKE_CURRENT_LIST_DIR}/python/bindings_docstring_keyed.cpp ${CMAKE_CURRENT_LIST_DIR}/python/bindings.cpp)
transfer_doc_string(${CMAKE_CURRENT_LIST_DIR}/python/bindings_docstring_keyed.hpp ${CMAKE_CURRENT_LIST_DIR}/python/bindings.hpp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPY_BINDINGS")
add_library(_sisso SHARED ${SISSOLIB_SOURCES})
......
......@@ -105,7 +105,7 @@ public:
std::string toString() const;
/**
* @brief Accessor function to the estimated property values
* @brief The estimated property values
*/
inline std::vector<double> predict(){return _prop_test_est;}
......@@ -129,7 +129,7 @@ public:
// DocString: model_test_rmse
/**
* @brief The testing rmse of the model
* @brief The test rmse of the model
*/
inline double test_rmse(){return util_funcs::norm(_test_error.data(), _n_samp_test) / std::sqrt(static_cast<double>(_n_samp_test));}
......@@ -181,7 +181,7 @@ public:
#ifdef PY_BINDINGS
// DocString: model_coefs
/**
* @brief Python Accessor functions to the coefficient array
* @brief The coefficient array for the model
* @return The coefficients as a python list
*/
inline py::list coefs()
......@@ -194,7 +194,7 @@ public:
// DocString: model_feats
/**
* @brief Python Accessor functions to the features
* @brief The features of the model
* @return A python list containing all of the features
*/
inline py::list feats()
......@@ -207,42 +207,42 @@ public:
// DocString: model_prop_train_est
/**
* @brief Python Accessor function to the estimation of the property
* @brief The estimation of the property
* @return _prop_train_est as a numpy ndarray
*/
inline np::ndarray prop_train_est(){return python_conv_utils::to_ndarray<double>(_prop_train_est);}
// DocString: model_prop_test_est
/**
* @brief Python Accessor function to the estimation of the properties test values
* @brief The estimation of the properties test values
* @return _prop_test_est as a numpy ndarray
*/
inline np::ndarray prop_test_est(){return python_conv_utils::to_ndarray<double>(_prop_test_est);}
// DocString: model_prop_train
/**
* @brief Python Accessor function to the property to be learned
* @brief The training data property to be learned
* @return _prop_train as a numpy ndarray
*/
inline np::ndarray prop_train(){return python_conv_utils::to_ndarray<double>(_prop_train);}
// DocString: model_prop_test
/**
* @brief Python Accessor function to the test values for the property
* @brief The test values for the property
* @return _prop_test as a numpy ndarray
*/
inline np::ndarray prop_test(){return python_conv_utils::to_ndarray<double>(_prop_test);}
// DocString: model_train_error
/**
* @brief Python Accessor function to the training error
* @brief The training error
* @return _train_error as a numpy ndarray
*/
inline np::ndarray train_error(){return python_conv_utils::to_ndarray<double>(_train_error);}
// DocString: model_test_error
/**
* @brief Python Accessor function to the test error
* @brief The test error
* @return _test_error as a numpy ndarray
*/
inline np::ndarray test_error(){return python_conv_utils::to_ndarray<double>(_test_error);}
......
......@@ -143,19 +143,19 @@ public:
// DocString: sisso_reg_n_samp
/**
* @brief Acessor function to the number of samples per feature
* @brief The number of samples per feature
*/
inline int n_samp(){return _n_samp;}
// DocString: sisso_reg_n_dim
/**
* @brief Acessor function to the maximum model dimensionality
* @brief The maximum model dimensionality
*/
inline int n_dim(){return _n_dim;}
// DocString: sisso_reg_n_residual
/**
* @brief Acessor function to the number of residuals each iteration of SIS acts on
* @brief The number of residuals each iteration of SIS acts on
*/
inline int n_residual(){return _n_residual;}
......@@ -210,41 +210,41 @@ public:
// DocString: sisso_reg_models_py
/**
* @brief Python Accessor function to the selected model (cpp definition in <python/descriptor_identifier/SISSORegressor.cpp)
* @brief The selected models (cpp definition in <python/descriptor_identifier/SISSORegressor.cpp)
* @return models as a python list
*/
py::list models_py();
// DocString: sisso_reg_prop_py
/**
* @brief Python Accessor function to the property to be learned
* @brief The property to be learned
* @return prop as a numpy array
*/
inline np::ndarray prop_py(){return python_conv_utils::to_ndarray<double>(_prop);}
// DocString: sisso_reg_prop_test_py
/**
* @brief Python Accessor function to the test values for the property
* @brief The test values for the property
* @return prop_test as a numpy array
*/
inline np::ndarray prop_test_py(){return python_conv_utils::to_ndarray<double>(_prop_test);}
// DocString: sisso_reg_task_sizes_train
/**
* @brief Python Accessor function to the number of samples per task in the training set
* @brief The number of samples per task in the training set
* @return task_sizes_train as a python list
*/
inline py::list task_sizes_train(){python_conv_utils::to_list<int>(_task_sizes_train);}
// DocString: sisso_reg_task_sizes_test
/**
* @brief Python Accessor function to the number of samples per task in the test set
* @brief The number of samples per task in the test set
* @return task_sizes_test as a python list
*/
inline py::list task_sizes_test(){python_conv_utils::to_list<int>(_task_sizes_test);}
/**
* @brief Python Accessor function to the error associated with the last tested model
* @brief The error associated with the last tested model
* @return error as a numpy array
*/
inline np::ndarray error_py(){return python_conv_utils::to_ndarray<double>(_error);}
......
......@@ -108,85 +108,86 @@ public:
void generate_feature_space(std::vector<double>& prop);
/**
* @brief Accessor function to the selected feature space
* @brief The selected feature space
*/
inline std::vector<node_ptr> phi_selected(){return _phi_selected;};
/**
* @brief Accessor function to the full feature space
* @brief The full feature space
*/
inline std::vector<node_ptr> phi(){return _phi;};
/**
* @brief Accessor function to the initial feature space
* @brief The initial feature space
*/
inline std::vector<node_ptr> phi0(){return _phi_0;};
/**
* @brief Accessor function to the vector of projection scores for SIS
* @brief The vector of projection scores for SIS
*/
inline std::vector<double> scores(){return _scores;}
/**
* @brief Accessor function to the MPI Communicator
* @brief The MPI Communicator
*/
inline std::shared_ptr<MPI_Interface> mpi_comm(){return _mpi_comm;}
/**
* @brief Accessor function to the vector storing the number of samples in each task
* @brief The vector storing the number of samples in each task
*/
inline std::vector<int> task_sizes(){return _task_sizes;}
// DocString: feat_space_feature_space_file
/**
* @brief Accessor function to the feature space filename
* @brief The feature space filename
*/
inline std::string feature_space_file(){return _feature_space_file;}
// DocString: feat_space_l_bound
/**
* @brief Accessor function to the minimum absolute value of the feature
* @brief The minimum absolute value of the feature
*/
inline double l_bound(){return _l_bound;}
// DocString: feat_space_u_bound
/**
* @brief Accessor function to the maximum absolute value of the feature
* @brief The maximum absolute value of the feature
*/
inline double u_bound(){return _u_bound;}
// DocString: feat_space_max_phi
/**
* @brief Accessor function to the maximum rung of the feature space
* @brief The maximum rung of the feature space
*/
inline int max_phi(){return _max_phi;}
// DocString: feat_space_n_sis_select
/**
* @brief Accessor function to the number of features selected in each SIS step
* @brief The number of features selected in each SIS step
*/
inline int n_sis_select(){return _n_sis_select;}
// DocString: feat_space_n_samp
/**
* @brief Accessor function to the number of samples per feature
* @brief The number of samples per feature
*/
inline int n_samp(){return _n_samp;}
// DocString: feat_space_n_feat
/**
* @brief Accessor function to the number of features in the feature space
* @brief The number of features in the feature space
*/
inline int n_feat(){return _n_feat;}
// DocString: feat_space_n_rung_store
/**
* @brief Accessor function to the number of rungs whose feature training data is stored in memory
* @brief The number of rungs whose feature training data is stored in memory
*/
inline int n_rung_store(){return _n_rung_store;}
// DocString: feat_space_n_rung_generate
/**
* @brief Accessor function to the number of rungs to be generated on the fly during SIS
* @brief The number of rungs to be generated on the fly during SIS
*/
inline int n_rung_generate(){return _n_rung_generate;}
......@@ -319,7 +320,7 @@ public:
/**
* @brief Wrapper function for SIS using a numpy array
*
* @param prop The property to perform SIS over as a numpy array
* @param prop(np.ndarray) The property to perform SIS over as a numpy array
*/
inline void sis(np::ndarray prop)
{
......@@ -331,7 +332,7 @@ public:
/**
* @brief Wrapper function for SIS using a python list
*
* @param prop The property to perform SIS over as a python list
* @param prop(list) The property to perform SIS over as a python list
*/
inline void sis(py::list prop)
{
......@@ -341,42 +342,42 @@ public:
// DocString: feat_space_phi_selected_py
/**
* @brief Python Accesor function to the selected feature space (cpp definition in <python/feature_creation/FeatureSpace.cpp>)
* @brief The selected feature space (cpp definition in <python/feature_creation/FeatureSpace.cpp>)
* @return _phi_selected as a python list
*/
py::list phi_selected_py();
// DocString: feat_space_phi0_py
/**
* @brief Python Accesor function to the initial feature space (cpp definition in <python/feature_creation/FeatureSpace.cpp>)
* @brief The initial feature space (cpp definition in <python/feature_creation/FeatureSpace.cpp>)
* @return _phi0 as a python list
*/
py::list phi0_py();
// DocString: feat_space_scores_py
/**
* @brief Python Accesor function to the vector of projection scores for SIS
* @brief The vector of projection scores for SIS
* @return _scores as a numpy array
*/
inline np::ndarray scores_py(){return python_conv_utils::to_ndarray<double>(_scores);};
// DocString: feat_space_task_sizes_py
/**
* @brief Python Accesor function to the vector storing the number of samples in each task
* @brief The vector storing the number of samples in each task
* @return _task_sizes as a python list
*/
inline py::list task_sizes_py(){return python_conv_utils::to_list<int>(_task_sizes);};
// DocString: feat_space_allowed_ops_py
/**
* @brief Python Accesor function to the list of allowed operator nodes
* @brief The list of allowed operator nodes
* @return _allowed_ops as a python list
*/
inline py::list allowed_ops_py(){return python_conv_utils::to_list<std::string>(_allowed_ops);}
// DocString: feat_space_start_gen_py
/**
* @brief Python Accesor function to list storing when each generation starts in phi
* @brief The index in _phi where each generation starts
* @return _start_gen as a python list
*/
inline py::list start_gen_py(){return python_conv_utils::to_list<int>(_start_gen);}
......
......@@ -150,23 +150,23 @@ public:
inline std::vector<double> value(){return _value;}
/**
* @brief Get the test_value of the feature
* @brief Get the test data for the feature
*/
inline std::vector<double> test_value(){return _test_value;}
// DocString: feat_node_set_value
/**
* @brief Set the value for the feature inside of the value storage arrays
* @brief Set the values of the training data for the feature inside of the value storage arrays
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline void set_value(int offset = -1){std::copy_n(_value.data(), _n_samp, value_ptr());}
// DocString: feat_node_set_test_value
/**
* @brief Set the test values for the feature inside of the value storage arrays
* @brief Set the values of the test data for the feature inside of the value storage arrays
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline void set_test_value(int offset = -1){if(!_selected) std::copy_n(_test_value.data(), _n_test_samp, test_value_ptr());}
......@@ -192,16 +192,16 @@ public:
inline NODE_TYPE type(){return NODE_TYPE::FEAT;}
/**
* @brief Accessor function to the pointer to where the feature's training data is stored
* @brief The pointer to where the feature's training data is stored
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline double* value_ptr(int offset = 0){return _selected ? node_value_arrs::get_d_matrix_ptr(_d_mat_ind) : node_value_arrs::get_value_ptr(_arr_ind, _feat_ind, offset);}
/**
* @brief Accessor function to the pointer to where the feature's test data is stored
* @brief The pointer to where the feature's test data is stored
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline double* test_value_ptr(int offset = 0){return node_value_arrs::get_test_value_ptr(_arr_ind, _feat_ind, offset);}
......
......@@ -87,17 +87,17 @@ public:
// DocString: model_node_set_value
/**
* @brief Set the value for the feature inside of the value storage arrays
* @brief Set the values of the training data for the feature inside of the value storage arrays
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline void set_value(int offset = -1){return;}
// DocString: model_node_set_test_value
/**
* @brief Set the test values for the feature inside of the value storage arrays
* @brief Set the values of the test data for the feature inside of the value storage arrays
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline void set_test_value(int offset = -1){return;}
......@@ -119,16 +119,16 @@ public:
inline NODE_TYPE type(){return NODE_TYPE::MODEL_FEATURE;}
/**
* @brief Accessor function to the pointer to where the feature's training data is stored
* @brief The pointer to where the feature's training data is stored
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline double* value_ptr(int offset = -1){return _value.data();}
/**
* @brief Accessor function to the pointer to where the feature's test data is stored
* @brief The pointer to where the feature's test data is stored
*
* @param offset Key to determine which part of the temporary storage array to look into
* @param offset(int) Key to determine which part of the temporary storage array to look into
*/
inline double* test_value_ptr(int offset = -1){return _test_value.data();}
......@@ -137,7 +137,7 @@ public:
/**
* @brief return the rung of the feature
*
* @param cur_rung The rung current rung of the feature tree (used to recursively calculate rung)
* @param cur_rung(int) The rung current rung of the feature tree (used to recursively calculate rung)
*/
inline int rung(int cur_rung = 0){return _rung;}
......
......@@ -119,8 +119,7 @@ public:
* @brief Reindex the feature
* @details re-index the feature to be continuous
*
* @param feat_ind the new feature index
* @param arr_ind the new array index
* @param ind(int) the new feature and array index
*/
inline void reindex(int ind){_feat_ind = ind; _arr_ind = ind;}
......@@ -129,39 +128,38 @@ public:
* @brief Reindex the feature
* @details re-index the feature to be continuous
*
* @param ind the new feature index
* @param arr_ind the new array index
* @param ind(int) the new feature index
* @param arr_ind(int) the new array index
*/
inline void reindex(int ind, int arr_ind){_feat_ind = ind; _arr_ind = arr_ind;}
// DocString: node_samp
/**
* @brief Acesssor function to get the number of samples
* @brief The number of samples
*/
inline int n_samp(){return _n_samp;}
// DocString: node_test_samp
/**
* @brief Acesssor function to get the number of samples in the test set
* @brief The number of samples in the test set
*/
inline int n_test_samp(){return _n_test_samp;}
// DocString: node_feat_ind
/**
* @brief Accessor function to get the feature ind
* @brief The feature index
*/
inline int feat_ind(){return _feat_ind;}
// DocString: node_arr_ind
/**
* @brief Accessor function to get the feature array index
* @brief The feature array index
*/
inline int arr_ind(){return _arr_ind;}
// DocString: node_selected
/**
* @brief Accessor function to _selected
* @return True if this feature was selected
* @brief True if feature is selected
*/
inline bool selected(){return _selected;}
......@@ -181,7 +179,7 @@ public:
inline void set_d_mat_ind(int ind){_d_mat_ind = ind;}
/**
* @brief Accessor function to _d_mat_ind
* @brief The descriptor matrix index
*/
inline int d_mat_ind(){return _d_mat_ind;}
......@@ -204,38 +202,38 @@ public:
/**
* @brief Get the test_value of the feature
* @brief Get the test data for the feature
*/
virtual std::vector<double> test_value() = 0;
// DocString: node_set_value
/**
* @brief Set the value for the feature inside of the value storage arrays