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 YAML support #24

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion Modules/DawgDevel.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SET(dawg_devel_LIBRARIES)
if(DAWG_DEVEL_ENABLE_GPERFTOOLS)
find_package(Gperftools COMPONENTS profiler)
if(GPERFTOOLS_FOUND)
message(S -DTATUS "DAWG_DEVEL: Profiling with gperftools enabled. Use CPUPROFILE environmental variable to turn on profiling and specify output file.")
message(STATUS "DAWG_DEVEL: Profiling with gperftools enabled. Use CPUPROFILE environmental variable to turn on profiling and specify output file.")
set(dawg_devel_LIBRARIES ${dawg_devel_LIBRARIES} GPERFTOOLS::GPERFTOOLS)
else()
message(FATAL_ERROR "Gperftools was not found. Please disable the flag DAWG_DEVEL_ENABLE_GPERFTOOLS and try again.")
Expand Down
107 changes: 100 additions & 7 deletions Modules/ExternalDep.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
include(ExternalProject)

# Prelim settings
SET(EXT_PREFIX ext_deps)
SET(EXT_DEPS_PREFIX ext_deps)

ADD_CUSTOM_TARGET(ext_projects)

IF(NOT "${CMAKE_VERSION}" VERSION_LESS 3.2)
SET(use_byproducts true)
Expand Down Expand Up @@ -43,7 +45,98 @@ IF(USE_STATIC_LIBS)
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
ENDIF(USE_STATIC_LIBS)

ADD_CUSTOM_TARGET(ext_projects)
################################################################################
# YAML-CPP
#
# See if YAML doesn't already exist on the system
find_package(YamlCpp)
IF(YAMLCPP_FOUND)
message(STATUS "Yaml-CPP library found and support for parsing .yaml files included.")

if(NOT TARGET YAML::YAML)
add_library(YAML::YAML STATIC IMPORTED GLOBAL)
set_target_properties(YAML::YAML PROPERTIES
IMPORTED_LOCATION "${YAMLCPP_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${YAMLCPP_INCLUDE_DIR}")
endif(NOT TARGET YAML::YAML)

# Finally, add the YAML definition for the pre-processor
ADD_DEFINITIONS(-DENABLE_YAML)
elseif(NOT YAMLCPP_FOUND AND BUILD_EXTERNAL_PROJECTS)
set(EXT_YAML_PREFIX "ext_yaml")

set(YAML_COMMIT 86c69bb73c497bd127afd9802d0aef8ba160f9c6)
set(YAML_URL https://github.com/jbeder/yaml-cpp/commit/${YAML_COMMIT})
set(YAML_SHA256 f69244b5027646aa87171780fced6095b396e79df07475fb1d20cfc64122445e)
set(YAML_REPO "https://github.com/jbeder/yaml-cpp.git")
set(YAML_TAG ${YAML_COMMIT})
set(YAML_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/${EXT_DEPS_PREFIX}/${EXT_YAML_PREFIX}")
set(YAML_BUILD_PATH "${YAML_PREFIX}-build")
set(YAML_INSTALL_PATH "${YAML_PREFIX}-install")
set(YAML_CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=${YAML_INSTALL_PATH})

message(STATUS "Downloading and building YAML-CPP from: [tag: ${YAML_TAG}] ${YAML_REPO}")
message(STATUS "Path to YAML-CPP: ${YAML_PREFIX}")
message(STATUS "YAML-CPP CMake args: ${YAML_CMAKE_ARGS}")

# Build Yaml-CPP
ExternalProject_Add(${EXT_YAML_PREFIX}
GIT_REPOSITORY ${YAML_REPO}
GIT_TAG ${YAML_TAG}
URL ${YAML_URL}
URL_HASH 256=${YAML_SHA256}
PREFIX ${YAML_PREFIX}
CMAKE_ARGS ${YAML_CMAKE_ARGS}
TMP_DIR "${YAML_PREFIX}-tmp"
STAMP_DIR "${YAML_PREFIX}-stamp"
INSTALL_DIR ${YAML_INSTALL_PATH}
#PATCH_COMMAND ""
#UPDATE_COMMAND ""
#CONFIGURE_COMMAND ""
SOURCE_DIR ${YAML_PREFIX}
BINARY_DIR ${YAML_BUILD_PATH}
#BUILD_IN_SOURCE true
#BUILD_ALWAYS true
#BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_EXECUTABLE} ${GMAKE_EXECUTABLE}
#INSTALL_COMMAND ${GMAKE_EXECUTABLE} install
TEST_COMMAND "")

set(YAML_FOUND TRUE)
set(YAMLCPP_INCLUDE_DIR "${YAML_INSTALL_PATH}/include/yaml-cpp/")

# May want to add a check to see if we're linking statically or not
if(WIN32 AND NOT UNIX)
set(YAMLCPP_LIBRARY "${YAML_INSTALL_PATH}/lib/libyaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
else()
set(YAMLCPP_LIBRARY "${YAML_INSTALL_PATH}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}yaml-cpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif(WIN32 AND NOT UNIX)

message(STATUS
"Including path to YAML headers: ${YAMLCPP_INCLUDE_DIR}")
message(STATUS
"Linking to built YAML library: ${YAMLCPP_LIBRARY}")

file(MAKE_DIRECTORY "${YAMLCPP_INCLUDE_DIR}")

if(NOT TARGET YAML::YAML)
add_library(YAML::YAML STATIC IMPORTED GLOBAL)
set_target_properties(YAML::YAML PROPERTIES
IMPORTED_LOCATION "${YAMLCPP_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${YAMLCPP_INCLUDE_DIR}")
endif(NOT TARGET YAML::YAML)

add_dependencies(YAML::YAML ${EXT_YAML_PREFIX})
add_dependencies(ext_projects YAML::YAML)
# Finally, add the YAML definition for the pre-processor
ADD_DEFINITIONS(-DENABLE_YAML)
elseif(NOT YAMLCPP_FOUND AND BUILD_EXTERNAL_PROJECTS)
else()
message(WARN
"Yaml-CPP is required to parse files in YAML format,
enable -DBUILD_EXTERNAL_PROJECTS:BOOL=ON to build YAML-CPP with DAWG")
endif(YAMLCPP_FOUND)
################################################################################


################################################################################
# THREADS
Expand Down Expand Up @@ -75,10 +168,10 @@ IF(NOT BUILD_EXTERNAL_PROJECTS_FORCED)
ENDIF()

IF(BUILD_EXTERNAL_PROJECTS AND NOT Boost_FOUND)
SET(boost_ext_libdir "${CMAKE_BINARY_DIR}/${EXT_PREFIX}/boost/lib")
SET(boost_ext_libdir "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/boost/lib")
SET(Boost_FOUND TRUE)
SET(Boost_VERSION 1.60.0)
SET(Boost_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/${EXT_PREFIX}/boost/include/")
SET(Boost_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/boost/include/")
FILE(MAKE_DIRECTORY "${Boost_INCLUDE_DIRS}")
SET(Boost_LIBRARY_DIRS "")
SET(BOOST_EXT_TARGET ext_boost)
Expand Down Expand Up @@ -118,12 +211,12 @@ IF(BUILD_EXTERNAL_PROJECTS AND NOT Boost_FOUND)

CONFIGURE_FILE(
"${CMAKE_SOURCE_DIR}/Modules/cmake_ext_boost_bootstrap.cmake.in"
"${CMAKE_BINARY_DIR}/${EXT_PREFIX}/cmake_ext_boost_bootstrap.cmake"
"${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/cmake_ext_boost_bootstrap.cmake"
IMMEDIATE @ONLY
)

SET(boost_bootstrap
"${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/${EXT_PREFIX}/cmake_ext_boost_bootstrap.cmake"
"${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/${EXT_DEPS_PREFIX}/cmake_ext_boost_bootstrap.cmake"
)

MARK_AS_ADVANCED(EXT_BOOST_TOOLSET EXT_BOOST_BOOTSTRAP_TOOLSET)
Expand Down Expand Up @@ -153,7 +246,7 @@ IF(BUILD_EXTERNAL_PROJECTS AND NOT Boost_FOUND)
ExternalProject_add(ext_boost
URL http://downloads.sourceforge.net/project/boost/boost/${Boost_VERSION}/boost_${boost_file_version}.tar.bz2
URL_MD5 65a840e1a0b13a558ff19eeb2c4f0cbe
PREFIX "${EXT_PREFIX}/boost"
PREFIX "${EXT_DEPS_PREFIX}/boost"
BUILD_IN_SOURCE TRUE
CONFIGURE_COMMAND ${boost_bootstrap}
BUILD_COMMAND ${boost_build}
Expand Down
47 changes: 47 additions & 0 deletions Modules/FindYamlCpp.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Locate the yaml-cpp library
#
# This module defines the following variables:
#
# YAMLCPP_LIBRARY the name of the library;
# YAMLCPP_INCLUDE_DIR where to find yaml-cpp include files.
# YAMLCPP_FOUND true if both the YAMLCPP_LIBRARY and YAMLCPP_INCLUDE_DIR have been found.
#
# To help locate the library and include file, you can define a
# variable called YAMLCPP_ROOT which points to the root of the YAMLCPP library
# installation.
#

# default search dirs
set( _yamlcpp_HEADER_SEARCH_DIRS
"/usr/include"
"/usr/local/include"
"C:/Program Files (x86)/yaml-cpp/include" )
set( _yamlcpp_LIB_SEARCH_DIRS
"/usr/lib"
"/usr/local/lib"
"C:/Program Files (x86)/yaml-cpp/lib-msvc110" )

# Check environment for root search directory
set( _yamlcpp_ENV_ROOT $ENV{yampcpp_ROOT} )
if( NOT YAMLCPP_ROOT AND _yamlcpp_ENV_ROOT )
set(YAMLCPP_ROOT ${_yamlcpp_ENV_ROOT} )
endif()

# Put user specified location at beginning of search
if( YAMLCPP_ROOT )
list( INSERT _yamlcpp_HEADER_SEARCH_DIRS 0 "${YAMLCPP_ROOT}/include" )
list( INSERT _yamlcpp_LIB_SEARCH_DIRS 0 "${YAMLCPP_ROOT}/yaml-cpp" )
endif()

# Search for the header
FIND_PATH(YAMLCPP_INCLUDE_DIR "yaml.h"
PATHS ${_yamlcpp_HEADER_SEARCH_DIRS}
PATH_SUFFIXES yaml-cpp)

# Search for the library
FIND_LIBRARY(YAMLCPP_LIBRARY NAMES yaml-cpp
PATHS ${_yamlcpp_LIB_SEARCH_DIRS} )

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(YAMLCPP DEFAULT_MSG
YAMLCPP_LIBRARY YAMLCPP_INCLUDE_DIR)
27 changes: 27 additions & 0 deletions dawg.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,33 @@ boolean: true|false
tree: Newick Format
vector: { value, value, ...}

UPDATED FOR YAML:
DAWG uses [YAML-CPP](https://github.com/jbeder/yaml-cpp) for parsing YAML format.

- The current parser only supports 1-level of nesting, for instance:
SecA:
Tree.Tree: "((Man:0.1,Monkey:0.1):0.2,Dawg:0.25);"

- This is not valid:
SecA:
Tree:
Tree: "((Man:0.1,Monkey:0.1):0.2,Dawg:0.25);"

- Auto-naming sections is done using the "AUTO" header (case-insenstive):
AUTO:
Tree.Tree: "((Man:0.1,Monkey:0.1):0.2,Dawg:0.25);"

- Inheritance is done using an "=", but no spaces are allowed:
SecB:
Tree.Tree: "((Llama:0.8,Squirrel:0.1):0.2,Kat:0.45);"
SecA=SecB:
Tree.Tree: "((Man:0.1,Monkey:0.1):0.2,Dawg:0.25);"

[] denotes sequence
{} denotes map
1 denotes a scalar value (where 1 can be any numeric value)
"" denotes a string

OPTIONS

Name Type Description
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ INSTALL(FILES
multiple-models.dawg
pseudogene.dawg
recombination.dawg
basic-dna.yaml
DESTINATION "${CMAKE_DATA_DIR}/examples")

14 changes: 14 additions & 0 deletions examples/basic-dna.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Shows the basic-dna.dawg example using YAML format
# @TODO "tree.tree" without any nesting is not valid unless it is already a child in a nest

Tree:
Tree: "((Man:0.1,Monkey:0.1):0.2,Dawg:0.25);"

Subst:
model: "HKY"
Params: [2.0, 1.0]
Freqs: [0.3, 0.2, 0.2, 0.3]
root:
Length: 1000
Sim:
Reps: 10
34 changes: 17 additions & 17 deletions examples/recombination.dawg
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Example: Specifying a recombination event and using autonamed sections

[[-]]
Subst.Model = jc
Root.Segment = 1
Root.Length = 60
Tree.Tree = ((A:0.02,B:0.02):0.2,(C:0.02):0.2);

[[-]]
Root.Code = 1
Root.Segment = 0
Root.Length = 60
Tree.Tree = ((A:0.02):0.2,(B:0.02,C:0.02):0.2);

[[-]]
Root.Segment = 2

# Example: Specifying a recombination event and using autonamed sections
[[-]]
Subst.Model = jc
Root.Segment = 1
Root.Length = 60
Tree.Tree = ((A:0.02,B:0.02):0.2,(C:0.02):0.2);
[[-]]
Root.Code = 1
Root.Segment = 0
Root.Length = 60
Tree.Tree = ((A:0.02):0.2,(B:0.02,C:0.02):0.2);
[[-]]
Root.Segment = 2
5 changes: 4 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ ELSE(LIBDAWG_USE_STATIC_LIBS)
TARGET_LINK_LIBRARIES(dawg libdawg2)
ENDIF(LIBDAWG_USE_STATIC_LIBS)

TARGET_LINK_LIBRARIES(dawg ${CMAKE_REQUIRED_LIBRARIES} ${Boost_LIBRARIES} ${dawg_devel_LIBRARIES})
TARGET_LINK_LIBRARIES(dawg ${CMAKE_REQUIRED_LIBRARIES} ${Boost_LIBRARIES} )
IF(YAMLCPP_FOUND)
TARGET_LINK_LIBRARIES(dawg YAML::YAML)
ENDIF(YAMLCPP_FOUND)

INSTALL(TARGETS dawg
RUNTIME DESTINATION bin
Expand Down
16 changes: 10 additions & 6 deletions src/include/dawg/trick.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ struct trick {
std::string name;
std::string inherits;
db_type db;


section() : name("_initial_"), inherits("_default_") { }
section(const std::string& nn, const std::string& ii) : name(nn), inherits(ii) { }

template<typename T>
inline void get(const std::string& k, T& r) const;
template<typename T, typename A>
Expand All @@ -51,14 +54,15 @@ struct trick {
bool parse(Iterator first, Iterator last);
template<typename Char, typename Traits>
inline bool parse_stream(std::basic_istream<Char, Traits>& is);

#if defined(ENABLE_YAML)
bool parse_yaml(const char* filepath);
#endif // ENABLE_YAML

trick() {
data.push_back(section());
data.back().name = "_initial_";
data.back().inherits = "_default_";
data.emplace_back("_initial_", "_default_");
}

inline void read_aliases();
inline void read_aliases();
};

template<typename T>
Expand Down
Loading