cassiopee-c-1.0.3/ 0000775 0000000 0000000 00000000000 12510053312 0013676 5 ustar 00root root 0000000 0000000 cassiopee-c-1.0.3/.cproject 0000664 0000000 0000000 00000007430 12510053312 0015514 0 ustar 00root root 0000000 0000000
cassiopee-c-1.0.3/.gitignore 0000664 0000000 0000000 00000000517 12510053312 0015671 0 ustar 00root root 0000000 0000000 # Compiled Object files
*.slo
*.lo
*.o
# Compiled Dynamic libraries
*.so
*.dylib
# Compiled Static libraries
*.lai
*.la
*.a
# cmake
CMakeCache.txt
CMakeFiles
cmake_install.cmake
doc/*
bin
Makefile
Cassiopee
test/test_cassiopee
CTestTestfile.cmake
Testing
# reports
cppunit-report.xml
cassiopee.dot
*.png
test/sequence.txt.cass.idx
cassiopee-c-1.0.3/.project 0000664 0000000 0000000 00000001452 12510053312 0015347 0 ustar 00root root 0000000 0000000
Cassiopeeorg.eclipse.cdt.managedbuilder.core.genmakebuilderclean,full,incremental,org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilderfull,incremental,org.eclipse.cdt.core.cnatureorg.eclipse.cdt.core.ccnatureorg.eclipse.cdt.managedbuilder.core.managedBuildNatureorg.eclipse.cdt.managedbuilder.core.ScannerConfigNature
cassiopee-c-1.0.3/CMakeLists.txt 0000664 0000000 0000000 00000003556 12510053312 0016447 0 ustar 00root root 0000000 0000000 cmake_minimum_required (VERSION 2.8)
enable_language(C CXX)
project (Cassiopee)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
link_directories(/usr/local/lib)
set (Cassiopee_VERSION_MAJOR 1)
set (Cassiopee_VERSION_MINOR 0)
set (PROJECT_SOURCE_DIR src)
set (PROJECT_BINARY_DIR ${CMAKE_BINARY_DIR}/bin)
set (PROJECT_DOC_DIR doc)
enable_testing()
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
#add_definitions( -DBOOST_ALL_NO_LIB )
unset(Boost_INCLUDE_DIR CACHE)
unset(Boost_LIBRARY_DIRS CACHE)
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost REQUIRED COMPONENTS iostreams serialization)
# add a target to generate API documentation with Doxygen
find_package(Doxygen)
if(DOXYGEN_FOUND)
configure_file(${PROJECT_SOURCE_DIR}/Doxyfile.in ${PROJECT_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc ALL
${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
endif(DOXYGEN_FOUND)
FIND_PACKAGE(OpenMP)
if(OPENMP_FOUND)
set(USE_OPENMP 1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
else()
set(USE_OPENMP 0)
endif()
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/CassiopeeConfig.h.in"
"${PROJECT_BINARY_DIR}/CassiopeeConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find CassiopeeConfig.h
include_directories("${PROJECT_BINARY_DIR}")
include_directories(${Boost_INCLUDE_DIR})
add_subdirectory (src)
add_subdirectory (test)
cassiopee-c-1.0.3/Changelog 0000664 0000000 0000000 00000000666 12510053312 0015520 0 ustar 00root root 0000000 0000000 1.0.3: 04/04/15 O. Sallou
- Bug fix on min pattern size to use when limiting index size.
1.0.2: 22/03/15 O. Sallou
- Add -l option to limit the size of the index. If not specified, index will
be done based on pattern length and indels. On next index/search operations
, if -l option or pattern+indel size are longer, index will be rebuild.
1.0.1: 16/04/14 O. Sallou
- Fix case of test failure on a few archs
1.0: First version
cassiopee-c-1.0.3/LICENSE 0000664 0000000 0000000 00000000173 12510053312 0014704 0 ustar 00root root 0000000 0000000 License: GNU GPL-3+
Full text is available at http://www.gnu.org/licenses/gpl-3.0.html
Copyright (c) 2013 Olivier Sallou
cassiopee-c-1.0.3/README.md 0000664 0000000 0000000 00000003731 12510053312 0015161 0 ustar 00root root 0000000 0000000 cassiopee-c
===========
Cassiopee index and search library C implementation.
It is a complete rewrite of the ruby Cassiopee gem.
It scan an input genomic sequence (dna/rna/protein) and search for a
subsequence with exact match or allowing substitutions (Hamming distance)
and/or insertion/deletions.
This program provides both a binary (Cassiopee) and a shared library.
Index is based on a suffix tree with compression. It is possible to save the
indexed sequence for later use without the need to reindex the whole sequence
(for large data sets).
See Cassiopee -h for all options.
Expected input sequence is a one-line sequence with no header. CassiopeeKnife (see later chapter) can be used to convert Fasta sequences in cassiopee input sequences.
Compilation dependencies
===========
* cppunit
* Google log (glog)
* tree.hh (included):
- Author: kasper.peeters (at) phi-sci.com
- http://tree.phi-sci.com/ under GNU GPL
* libboost-serialization-dev,libboost-iostreams-dev
Runtime dependencies
===================
* Google log (glog)
* libboost-serialization, libboost-iostreams
Compilation
===========
cmake -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_BUILD_TYPE=Debug .
make
Valgrind
=======
valgrind --leak-check=full bin/Cassiopee -s test/sequence.txt -p ggc
Static analysis
==============
CXX=/usr/share/clang/scan-build/c++-analyzer cmake .
Tests
=====
bin/test_cassiopee
or
cd test; ctest -V
Tree graph generation
=====================
API provides the graph method to generate a cassiopee.dot file.
To generate the image from the file:
dot -Tpng cassiopee.dot > cassiopee.png
Documentation
============
doxygen bin/Doxyfile
BUGS
====
CassiopeeKnife
=============
Convert an input Fasta sequence in a cassiopee input format (one line sequence
with no header).
TODO
====
COPYRIGHT
========
See license file.
Code under src/tree from http://tree.phi-sci.com/, copyright kasper.peeters@phi-sci.com
cassiopee-c-1.0.3/src/ 0000775 0000000 0000000 00000000000 12510053312 0014465 5 ustar 00root root 0000000 0000000 cassiopee-c-1.0.3/src/CMakeLists.txt 0000664 0000000 0000000 00000002107 12510053312 0017225 0 ustar 00root root 0000000 0000000
set(Cassie_VERSION_STRING ${Cassiopee_VERSION_MAJOR}.${Cassiopee_VERSION_MINOR}.0)
add_library(cassie SHARED cassiopee.cxx)
set_target_properties(cassie PROPERTIES VERSION ${Cassie_VERSION_STRING} SOVERSION ${Cassiopee_VERSION_MAJOR})
add_executable(cassiopee cassie.cxx)
add_executable(cassiopeeknife knife.cxx)
target_link_libraries(cassie glog ${Boost_LIBRARIES} )
target_link_libraries(cassiopee cassie glog ${Boost_LIBRARIES} )
target_link_libraries(cassiopeeknife cassie glog ${Boost_LIBRARIES} )
# add the install targets
install (TARGETS cassiopee DESTINATION bin)
install (TARGETS cassiopeeknife DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/CassiopeeConfig.h"
DESTINATION include)
install (TARGETS cassie DESTINATION lib)
set(HS Cassiopee.h tree/tree.hh tree/tree_util.hh)
MACRO(INSTALL_HEADERS_WITH_DIRECTORY HEADER_LIST)
FOREACH(HEADER ${${HEADER_LIST}})
STRING(REGEX MATCH "(.*)[/\\]" DIR ${HEADER})
INSTALL(FILES ${HEADER} DESTINATION include/${DIR})
ENDFOREACH(HEADER)
ENDMACRO(INSTALL_HEADERS_WITH_DIRECTORY)
INSTALL_HEADERS_WITH_DIRECTORY(HS)
cassiopee-c-1.0.3/src/Cassiopee.h 0000664 0000000 0000000 00000023462 12510053312 0016560 0 ustar 00root root 0000000 0000000 #include
#include
#include
#include "tree/tree.hh"
#include "CassiopeeConfig.h"
#include
#include
#include
#include
// Provide an implementation of serialize for std::list
#include
using namespace std;
/**
* Object to manage insertion and deletions
*/
class Match {
public:
/**
* define equality between matches
*/
bool operator==(const Match& p) const {
return pos == p.pos && in+del == p.in + p.del;
}
/**
* Number of insertion error
*/
int in;
/**
* Number of deletion error
*/
int del;
/**
* Number of substitution error
*/
int subst;
long pos;
Match();
};
/**
* Node in the suffix tree
*
* If tree is reduced (DO_REDUCTION=1), memory usage is highly reduced, keeping in memory only the branching nodes.
* Search is made after that looking at branch nodes and sequence content between nodes.
* In addition, data from file are analysed per chunk, limiting again loaded data in memory.
*
* This treatment requires however more disk usage (reads) and tree manipulations, increasing the index and search time for a gain on memory requirements.
*/
class TreeNode {
public:
/**
* Character to match
*/
char c;
/**
* List of positions in sequence matching this node
*/
list positions;
/**
* When tree is reduced, store the location of next characters in input sequence file.
* Reduction can be made from a branch up to the leaf or between 2 branches.
* If next_pos is equal to -1, then no reduction is made.
*/
long next_pos;
/**
* Length of remaining data to read in sequence file
*/
long next_length;
/**
* Creates a node from a char
*
* \param nc character for this node
*/
TreeNode(char nc);
/**
* Creates a node from a char
*
* \param nc character for this node
* \param pos position of the character in the sequence
*/
TreeNode(char nc, long pos);
TreeNode();
private:
friend class boost::serialization::access;
template
void serialize(Archive & ar, const unsigned int /*version*/)
{
ar & c;
ar & next_pos;
ar & next_length;
ar & positions;
}
};
#ifndef __CASSIOPEE_H_
#define __CASSIOPEE_H_
//inline std::ostream& operator<<(std::ostream &strm, const TreeNode &a) {
// return strm << "TreeNode(" << a.c << ")";
//}
#endif
/**
* Cassiopee indexer
*
* Index an input file
*/
class CassieIndexer {
public:
/**
* Main contructor
*
* \param path Path to the sequence file, sequence must be a one-line sequence.
*/
CassieIndexer(const char* path);
~CassieIndexer();
/**
* Save the index in a file
*/
void save();
/**
* Load index from a file
*/
void load();
/**
* Generates a dot file representing the tree.
*/
void graph();
/**
* Generates a dot file representing the tree up to depth
*
* \param depth Max depth to print
*/
void graph(int depth);
/**
* Get the suffix content from a position
*
* \param pos Position in the file
* \return the suffix string
*/
string getSuffix(long pos);
/**
* Launch the indexation of the input sequence
*/
void index();
/**
* Get the tree matching the indexed sequence
*/
tree* getTree();
/**
* List of positions in original sequence matching the search
*/
list matches;
/**
* Allow tree reduction
*/
bool do_reduction;
/**
* Get char from suffix located at position pos.
*/
char getCharAtSuffix(long pos);
/**
* Fills suffix tree with input suffix
*
* \param pos Position of suffix in sequence
*/
void filltree(long pos);
/**
* Max depth to graph
*/
long max_depth;
/**
* Max depth to index, can limit index size if pattern to search are known
* of a maximum size
*/
long max_index_depth;
long seq_length;
/**
* Checks if index has been loaded from a saved index or if index has been build dynamically
*/
bool index_loaded_from_file();
private:
list serialized_nodes;
bool loaded_from_file;
const char* filename;
ifstream seqstream;
tree tr;
const long MAX_SUFFIX;
long suffix_position;
char* suffix;
/**
* Graph the children of node
*/
long graphNode(tree::iterator node, long counter, ofstream& myfile, int maxdepth);
/**
* Extract parts of suffix located at pos from stream with a max size of MAX_SUFFIX.
*/
char* loadSuffix(long pos);
/**
* Reset current suffix; Mandatory before calling getCharAtSuffix on a new suffix
*/
void reset_suffix();
/**
* Fills a tree branch with the suffix starting at suffix_pos
*
* \param sib Insert at node sib.
* \param suffix_pos Starting inserting from suffix position index
* \param pos Position of suffix in sequence
*/
void fillTreeWithSuffix(tree::iterator sib, long suffix_pos, long pos);
void fillTreeWithSuffix(long suffix_pos, long pos);
};
/**
* Utility functions
*/
class CassiopeeUtils {
public:
/**
* Transform a Fasta input sequence in a sequence manageable by index.
*/
static void transform_fasta(const string in, const string out);
};
/**
* Ambiguity character matches for DNA
*/
class Ambiguous {
public:
/**
* Checks if a char is equal to an other according to ambiguity
*
* \param a input char
* \param b input char
* \return true if characters match
*/
static bool isequal(char a, char b);
private:
/**
* Compares input character with a list of possible matches
*
* \param a input char, non ambiguous
* \param b list of possible matches for ambiguity
* \param len length of b array
* \return true if a match one character of b
*/
static bool ismatchequal(char a, const char b[], int len);
static const char K_MATCH[];
static const char M_MATCH[];
static const char R_MATCH[];
static const char Y_MATCH[];
static const char S_MATCH[];
static const char W_MATCH[];
static const char B_MATCH[];
static const char V_MATCH[];
static const char H_MATCH[];
static const char D_MATCH[];
static const char N_MATCH[];
};
struct per_position
{
inline bool operator() (const Match* struct1, const Match* struct2)
{
return (struct1->pos < struct2->pos);
}
};
/**
* Search object
*
*/
class CassieSearch {
public:
/**
* Main constructor
*
* \param index_ref Indexer for sequence
*/
CassieSearch(CassieIndexer* index_ref);
~CassieSearch();
/**
* Remove matches with same position and same length.
*/
void removeDuplicates();
/**
* Used to store max errors allowed
*/
Match* match_limits;
/**
* List of positions in original sequence matching the search
*/
list matches;
/**
* Allow alphabet ambiguity search. False by default.
* N are by default ignored. To allow N matching, the nmax attribute must be set
*/
bool ambiguity;
/**
* Allow N matching with alphabet ambiguity. nmax defines the maximum number of consecutive N allowed in match.
*/
int nmax;
/**
* Search mode:
*
* - 0: DNA
* - 1: RNA
* - 2: Protein
*/
int mode;
/**
* Search for a string in the indexed sequence
*
* \param suffix pattern to search
* \param clear Clear existing matches?
*/
void search(string suffix, bool clear);
/**
* Search for a string in the indexed sequence.
* Clear all previous matches.
*
* \param suffix pattern to search
*/
void search(string suffix);
/**
* Search for multiple strings
*
* \param array of patterns to search
*/
void search(string suffixes[]);
/**
* Compare two chars, with ambiguity is option is set
*/
bool isequal(char a,char b);
/**
* Maximum number of insertion or deletion
*/
int max_indel;
/**
* Maximum number of substitution
*/
int max_subst;
long pattern_length;
/**
* Sort matches according to positions i nascending order
*/
void sort();
private:
/**
* Compare two Match pointers
*/
static bool same_match (Match* first, Match* second)
{ return ( *first == *second ); }
CassieIndexer* indexer;
/**
* Sets all matching positions in matches from node
*
* \param sib Base node to search through in the tree
* \param nbSubst Number of substition found
* \param nbIn Number of insertion found
* \param nbDel Number of deletion found
*/
void getMatchesFromNode(tree::iterator sib, const int nbSubst, const int nbIn, const int nbDel);
/**
* Compare suffix at a specific start root node (check with root children).
*
* \param suffix Suffix to analyse
* \param suffix_pos position on suffix
* \param root Tree node root to analyse, starts with first child
* \param nbSubst current number of substitutions found
* \param nbIn current number of insertions found
* \param nbDel current number of deletions found
* \param nbN current consecutive N found
*/
void searchAtNode(string suffix, const long suffix_pos, const tree::iterator root, int nbSubst, int nbIn, int nbDel, int nbN);
/**
* Compare suffix at a specific start root node (check with root children).
* \param suffix Suffix to analyse
* \param suffix_pos position on suffix
* \param root Tree node root to analyse
* \param start_node root child node to start with (no first element)
* \param nbSubst current number of substitutions found
* \param nbIn current number of insertions found
* \param nbDel current number of deletions found
* \param nbN current consecutive N found
*/
void searchAtNode(string suffix, const long suffix_pos, const tree::iterator root, const tree::iterator start_node, int nbSubst, int nbIn, int nbDel, int nbN);
/**
* Compare suffix in reducted string at node sib.
* \return true if matched
*/
bool searchAtreduction(const string suffix, const tree::iterator sib, long counter, long tree_reducted_pos, int nbSubst, int nbIn, int nbDel, int nbN);
};
cassiopee-c-1.0.3/src/CassiopeeConfig.h.in 0000664 0000000 0000000 00000000347 12510053312 0020310 0 ustar 00root root 0000000 0000000 // the configured options and settings for Cassiopee
#define Cassiopee_VERSION_MAJOR @Cassiopee_VERSION_MAJOR@
#define Cassiopee_VERSION_MINOR @Cassiopee_VERSION_MINOR@
#define use_openmp @USE_OPENMP@
#define SUFFIX_CHUNK_SIZE 10 cassiopee-c-1.0.3/src/Doxyfile.in 0000664 0000000 0000000 00000223626 12510053312 0016613 0 ustar 00root root 0000000 0000000 # Doxyfile 1.7.6.1
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or sequence of words) that should
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.
PROJECT_NAME = "Cassiopee"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = @Cassiopee_VERSION_MAJOR@.@Cassiopee_VERSION_MINOR@
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
# a quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "Suffix indexer and search tool"
# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory.
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = @PROJECT_DOC_DIR@
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.
CREATE_SUBDIRS = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
# in this list, if found as the leading text of the brief description, will be
# stripped from the text and the result after processing the whole list, is
# used as the annotated text. Otherwise, the brief description is used as-is.
# If left blank, the following values are used ("$name" is automatically
# replaced with the name of the entity): "The $name class" "The $name widget"
# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"
ABBREVIATE_BRIEF =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
# the reader which header file to include in order to use a class.
# If left blank only the name of the header file containing the class
# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 8
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding
# "class=itcl::class" will allow you to use the command class in the
# itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = NO
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.
OPTIMIZE_OUTPUT_VHDL = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given extension.
# Doxygen has a built-in mapping, but you can override or extend it using this
# tag. The format is ext=language, where ext is a file extension, and language
# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
EXTENSION_MAPPING =
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also makes the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
# the same type (for instance a group of public functions) to be put as a
# subgroup of that type (e.g. under the Public Functions section). Set it to
# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING = YES
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
# unions are shown inside the group in which they are included (e.g. using
# @ingroup) instead of on a separate page (for HTML and Man pages) or
# section (for LaTeX and RTF).
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
# unions with only public data fields will be shown inline in the documentation
# of the scope in which they are defined (i.e. file, namespace, or group
# documentation), provided this scope is documented. If set to NO (the default),
# structs, classes, and unions are shown on a separate page (for HTML and Man
# pages) or section (for LaTeX and RTF).
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
TYPEDEF_HIDES_STRUCT = NO
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is
# probably good enough. For larger projects a too small cache size can cause
# doxygen to be busy swapping symbols to and from disk most of the time
# causing a significant performance penalty.
# If the system has enough physical memory increasing the cache will improve the
# performance by keeping more symbols in memory. Note that the value works on
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
SYMBOL_CACHE_SIZE = 0
# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
# their name and scope. Since this can be an expensive process and often the
# same symbol appear multiple times in the code, doxygen keeps a cache of
# pre-resolved symbols. If the cache is too small doxygen will become slower.
# If the cache is too large, memory is wasted. The cache size is given by this
# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespaces are hidden.
EXTRACT_ANON_NSPACES = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
# documentation blocks found inside the body of a function.
# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.
HIDE_IN_BODY_DOCS = NO
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower-case letters. If set to YES upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
# rather than with sharp brackets.
FORCE_LOCAL_INCLUDES = NO
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
# brief documentation of file, namespace and class members alphabetically
# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
# will sort the (brief and detailed) documentation of class members so that
# constructors and destructors are listed first. If set to NO (the default)
# the constructors will appear in the respective orders defined by
# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
SORT_MEMBERS_CTORS_1ST = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
# the group names will appear in their defined order.
SORT_GROUP_NAMES = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
# sorted by fully-qualified names, including namespaces. If set to
# NO (the default), the class list will be sorted only by class name,
# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the
# alphabetical list.
SORT_BY_SCOPE_NAME = NO
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
# do proper type resolution of all parameters of a function it will reject a
# match between the prototype and the implementation of a member function even
# if there is only one candidate or it is obvious which candidate to choose
# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
# will still accept a match between prototype and implementation in such cases.
STRICT_PROTO_MATCHING = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or macro consists of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and macros in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = NO
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.
SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page.
# This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.
SHOW_NAMESPACES = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command , where is the value of
# the FILE_VERSION_FILTER tag, and is the name of an input file
# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. The create the layout file
# that represents doxygen's defaults, run doxygen with the -l option.
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files
# containing the references data. This must be a list of .bib files. The
# .bib extension is automatically appended if omitted. Using this command
# requires the bibtex tool to be installed. See also
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
# feature you need bibtex and perl available in the search path.
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some
# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.
WARN_IF_DOC_ERROR = YES
# The WARN_NO_PARAMDOC option can be enabled to get warnings for
# functions that are documented, but have no documentation for their parameters
# or return value. If set to NO (the default) doxygen will only warn about
# wrong or incomplete parameter documentation, but not about the absence of
# documentation.
WARN_NO_PARAMDOC = NO
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text. Optionally the format may contain
# $version, which will be replaced by the version of the file (if it could
# be obtained via FILE_VERSION_FILTER)
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = @CMAKE_CURRENT_SOURCE_DIR@/@PROJECT_SOURCE_DIR@
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
# the list of possible encodings.
INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl
FILE_PATTERNS =
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories. Note that the wildcards are matched
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command , where
# is the value of the INPUT_FILTER tag, and is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
# If FILTER_PATTERNS is specified, this tag will be
# ignored.
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis.
# Doxygen will compare the file name with each pattern and apply the
# filter if there is a match.
# The filters are a list of the form:
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
# info on how filters are used. If FILTER_PATTERNS is empty or if
# non of the patterns match the file name, INPUT_FILTER is applied.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
# and it is also possible to disable source filtering for a specific pattern
# using *.ext= (so without naming a filter). This option only has effect when
# FILTER_SOURCE_FILES is enabled.
FILTER_SOURCE_PATTERNS =
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = NO
# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
# link to the source code.
# Otherwise they will link to the documentation.
REFERENCES_LINK_SOURCE = YES
# If the USE_HTAGS tag is set to YES then the references to source code
# will point to the HTML generated by the htags(1) tool instead of doxygen
# built-in source browser. The htags tool is part of GNU's global source
# tagging system (see http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.
USE_HTAGS = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = YES
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header. Note that when using a custom header you are responsible
# for the proper inclusion of any scripts and style sheets that doxygen
# needs, which is dependent on the configuration options used.
# It is advised to generate a default header using "doxygen -w html
# header.html footer.html stylesheet.css YourConfigFile" and then modify
# that header. Note that the header is subject to change so you typically
# have to redo this when upgrading to a newer version of doxygen or when
# changing the value of configuration settings such as GENERATE_TREEVIEW!
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# style sheet in the HTML output directory as well, or it will be erased!
HTML_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
# the files will be copied as-is; there are no commands or markers available.
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the style sheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://en.wikipedia.org/wiki/Hue for more information.
# For instance the value 0 represents red, 60 is yellow, 120 is green,
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.
HTML_COLORSTYLE_HUE = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
# grayscales only. A value of 255 will produce the most vivid colors.
HTML_COLORSTYLE_SAT = 100
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
# the luminance component of the colors in the HTML output. Values below
# 100 gradually make the output lighter, whereas values above 100 make
# the output darker. The value divided by 100 is the actual gamma applied,
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
# and 100 does not change the gamma.
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.
HTML_TIMESTAMP = YES
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = NO
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
# integrated development environment, introduced with OSX 10.5 (Leopard).
# To create a documentation set, doxygen will generate a Makefile in the
# HTML output directory. Running make will produce the docset in that
# directory and running "make install" will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
# it at startup.
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
GENERATE_DOCSET = NO
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# feed. A documentation feed provides an umbrella under which multiple
# documentation sets from a single provider (such as a company or product suite)
# can be grouped.
DOCSET_FEEDNAME = "Doxygen generated docs"
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
# should uniquely identify the documentation set bundle. This should be a
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
# will append .docset to the name.
DOCSET_BUNDLE_ID = org.doxygen.Project
# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
# written to the html output directory.
CHM_FILE =
# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
# be used to specify the location (absolute path including file name) of
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.
HHC_LOCATION =
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.
CHM_INDEX_ENCODING =
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND = NO
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
# that can be used as input for Qt's qhelpgenerator to generate a
# Qt Compressed Help (.qch) of the generated HTML documentation.
GENERATE_QHP = NO
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
# be used to specify the file name of the resulting .qch file.
# The path specified is relative to the HTML output folder.
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace
QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#virtual-folders
QHP_VIRTUAL_FOLDER = doc
# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
# add. For more information please see
# http://doc.trolltech.com/qthelpproject.html#custom-filters
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see
#
# Qt Help Project / Custom Filters.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's
# filter section matches.
#
# Qt Help Project / Filter Attributes.
QHP_SECT_FILTER_ATTRS =
# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
# be used to specify the location of Qt's qhelpgenerator.
# If non-empty doxygen will try to run qhelpgenerator on the generated
# .qhp file.
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
# will be generated, which together with the HTML files, form an Eclipse help
# plugin. To install this plugin and make it available under the help contents
# menu in Eclipse, the contents of the directory containing the HTML and XML
# files needs to be copied into the plugins directory of eclipse. The name of
# the directory within the plugins directory should be the same as
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
# this name.
ECLIPSE_DOC_ID = org.doxygen.Project
# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
# at top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it. Since the tabs have the same information as the
# navigation tree you can set this option to NO if you already set
# GENERATE_TREEVIEW to YES.
DISABLE_INDEX = NO
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to YES, a side panel will be generated
# containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
# Windows users are probably better off using the HTML help feature.
# Since the tree basically has the same information as the tab index you
# could consider to set DISABLE_INDEX to NO when enabling this option.
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
# (range [0,1..20]) that doxygen will group on one line in the generated HTML
# documentation. Note that a value of 0 will completely suppress the enum
# values from appearing in the overview section.
ENUM_VALUES_PER_LINE = 4
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
# and Class Hierarchy pages using a tree view instead of an ordered list.
USE_INLINE_TREES = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
# links to external symbols imported via tag files in a separate window.
EXT_LINKS_IN_WINDOW = NO
# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# when you change the font size after a successful doxygen run you need
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
# in the HTML output before the changes have effect.
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
# (see http://www.mathjax.org) which uses client side Javascript for the
# rendering instead of using prerendered bitmaps. Use this if you do not
# have LaTeX installed or if you want to formulas look prettier in the HTML
# output. When enabled you also need to install MathJax separately and
# configure the path to it using the MATHJAX_RELPATH option.
USE_MATHJAX = NO
# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
# directory is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the
# mathjax.org site, so you can quickly see the result without installing
# MathJax, but it is strongly recommended to install a local copy of MathJax
# before deployment.
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
# names that should be enabled during MathJax rendering.
MATHJAX_EXTENSIONS =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
# (GENERATE_DOCSET) there is already a search function so this one should
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvantages are that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
# the generated latex document. The footer should contain everything after
# the last chapter. If it is left blank doxygen will generate a
# standard footer. Notice: only use this tag if you know what you are doing!
LATEX_FOOTER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES = NO
# If LATEX_SOURCE_CODE is set to YES then doxygen will include
# source code with syntax highlighting in the LaTeX output.
# Note that which sources are shown also depends on other settings
# such as SOURCE_BROWSER.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
# http://en.wikipedia.org/wiki/BibTeX for more info.
LATEX_BIB_STYLE = plain
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load style sheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES Doxygen will
# generate a Perl module file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.
GENERATE_PERLMOD = NO
# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.
PERLMOD_LATEX = NO
# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
# nicely formatted so it can be parsed by a human reader.
# This is useful
# if you want to understand what is going on.
# On the other hand, if this
# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.
PERLMOD_PRETTY = YES
# The names of the make variables in the generated doxyrules.make file
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# pointed to by INCLUDE_PATH will be searched when a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. To prevent a macro definition from being
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition that
# overrules the definition found in the source code.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all references to function-like macros
# that are alone on a line, have an all uppercase name, and do not end with a
# semicolon, because these will confuse the parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
# The TAGFILES option can be used to specify one or more tagfiles.
# Optionally an initial location of the external documentation
# can be added for each tagfile. The format of a tag file without
# this location is as follows:
#
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
#
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where "loc1" and "loc2" can be relative or absolute paths or
# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
# or super classes. Setting the tag to NO turns the diagrams off. Note that
# this option also works with HAVE_DOT disabled, but it is recommended to
# install and use dot, since it yields more powerful graphs.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) doxygen will
# base this on the number of processors available in the system. You can set it
# explicitly to a value larger than 0 to get control over the balance
# between CPU load and processing speed.
DOT_NUM_THREADS = 0
# By default doxygen will use the Helvetica font for all dot files that
# doxygen generates. When you want a differently looking font you can specify
# the font name using DOT_FONTNAME. You need to make sure dot is able to find
# the font, which can be done by putting it in a standard location or by setting
# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
# directory containing the font.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the Helvetica font.
# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
# set the path where dot can find it.
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies
GROUP_GRAPHS = YES
# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
UML_LOOK = NO
# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = NO
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable call graphs
# for selected functions only using the \callgraph command.
CALL_GRAPH = NO
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
# doxygen will generate a caller dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable caller
# graphs for selected functions only using the \callergraph command.
CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will generate a graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
# then doxygen will show the dependencies a directory has on other directories
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are svg, png, jpg, or gif.
# If left blank png will be used. If you choose svg you need to set
# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible in IE 9+ (other browsers do not have this requirement).
DOT_IMAGE_FORMAT = png
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
# Note that this requires a modern browser other than Internet Explorer.
# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible. Older versions of IE do not have SVG support.
INTERACTIVE_SVG = NO
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the
# \mscfile command).
MSCFILE_DIRS =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
# nodes that will be shown in the graph. If the number of nodes in a graph
# becomes larger than this value, doxygen will truncate the graph, which is
# visualized by representing a node as a red box. Note that doxygen if the
# number of direct children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
DOT_GRAPH_MAX_NODES = 50
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes
# that lay further from the root node will be omitted. Note that setting this
# option to 1 or 2 may greatly reduce the computation time needed for large
# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not
# seem to support this out of the box. Warning: Depending on the platform used,
# enabling this option may lead to badly anti-aliased labels on the edges of
# a graph (i.e. they become hard to read).
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.
DOT_MULTI_TARGETS = YES
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
cassiopee-c-1.0.3/src/cassie.cxx 0000664 0000000 0000000 00000016425 12510053312 0016470 0 ustar 00root root 0000000 0000000 // A simple program that computes the square root of a number
#include
#include
#include
#include
#include
#include "Cassiopee.h"
using namespace std;
void showUsage() {
fprintf(stdout,"Usage:\n");
fprintf(stdout,"\t-l: maximum index depth / max pattern size\n");
fprintf(stdout,"\t-u: save index for later use\n");
fprintf(stdout,"\t-s: sequence to index\n");
fprintf(stdout,"\t-p: pattern to search\n");
fprintf(stdout,"\t-f: file containing pattern to search\n");
fprintf(stdout,"\t-o: output file\n");
fprintf(stdout,"\t-r: apply tree reduction\n");
fprintf(stdout,"\t-m: search mode: 0=DNA, 1=RNA, 2=Protein\n");
fprintf(stdout,"\t-a: allow alphabet ambiguity search\n");
fprintf(stdout,"\t-n: max consecutive N allowed matches in search\n");
fprintf(stdout,"\t-e: max substitution allowed matches in search\n");
fprintf(stdout,"\t-i: max indel allowed matches in search\n");
fprintf(stdout,"\t-g: generates a dot file of the graph\n");
fprintf(stdout,"\t-d: max depth of the graph\n");
fprintf(stdout,"\t-t: output format: 0:tsv (default), 1:json\n");
fprintf(stdout,"\t-x: minimum position in sequence\n");
fprintf(stdout,"\t-y: maximum position in sequence\n");
fprintf(stdout,"\t-v: show version\n");
fprintf(stdout,"\t-h: show this message\n");
}
void showVersion() {
fprintf(stdout,"%s Version %d.%d\n",
"Cassiopee",
Cassiopee_VERSION_MAJOR,
Cassiopee_VERSION_MINOR);
}
int main (int argc, char *argv[])
{
if (argc == 1) {
showVersion();
showUsage();
return 1;
}
int c;
char* sequence=NULL;
string pattern;
bool is_pattern = false;
char* pattern_file=NULL;
opterr = 0;
bool reduction = false;
bool ambiguity = false;
int nmax = 0;
// DNA by default
int mode = 0;
int max_subst = 0;
int max_indel = 0;
int min = 0;
int max = -1;
long max_index_depth = 0;
bool graph = false;
long max_graph = 0;
int format = 0;
string out_file_name;
bool save = false;
while ((c = getopt (argc, argv, "ud:ge:i:m:arhvs:p:n:t:o:f:x:y:l:")) != -1)
switch (c)
{
case 'l':
max_index_depth = atol(optarg);
case 'u':
save = true;
break;
case 's':
sequence = strdup(optarg);
break;
case 'p':
pattern = string(optarg);
is_pattern = true;
break;
case 'o':
out_file_name = string(optarg);
break;
case 'f':
pattern_file = strdup(optarg);
is_pattern = true;
break;
case 'h':
showUsage();
return 0;
case 'g':
graph = true;
break;
case 'd':
max_graph = atol(optarg);
break;
case 'x':
min = atol(optarg);
break;
case 'y':
max = atol(optarg);
break;
case 'r':
reduction = true;
break;
case 'a':
ambiguity = true;
break;
case 'n':
nmax = atoi(optarg);
break;
case 't':
format = atoi(optarg);
break;
case 'e':
max_subst = atoi(optarg);
break;
case 'i':
max_indel = atoi(optarg);
break;
case 'm':
mode = atoi(optarg);
break;
case 'v':
showVersion();
return 0;
case '?':
if (optopt == 's' || optopt == 'p')
fprintf (stderr, "Option requires an argument.\n");
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr,
"Unknown option character `\\x%x'.\n",
optopt);
return 1;
default:
abort ();
}
if(sequence==NULL|| ! is_pattern) {
fprintf (stderr,
"Sequence file or pattern not specified in command line.\n");
return 1;
}
if(out_file_name.size()==0) {
fprintf (stderr,
"Output file name specified in command line.\n");
return 1;
}
//FLAGS_logtostderr = 1;
google::InitGoogleLogging(sequence);
//google::SetLogDestination(google::GLOG_INFO,string(dirname(sequence)).c_str() );
if(pattern_file!=NULL) {
ifstream pfile(pattern_file);
if(pfile.is_open()) {
// Read only first line
while( getline(pfile, pattern)) {
if(pattern.at(0)!='>') {
DLOG(INFO) << "Search pattern " << pattern;
break;
}
}
pfile.close();
}
}
long max_pattern_size = std::max(max_index_depth, (long)(pattern.size()+max_indel+1));
CassieIndexer* indexer = new CassieIndexer(sequence);
if(reduction) {
indexer->do_reduction = true;
}
indexer->max_index_depth = max_pattern_size;
indexer->max_depth = max_graph;
indexer->index();
if(save) {
indexer->save();
}
if(graph) {
indexer->graph(max_graph);
}
DLOG(INFO) << "Tree size: " <getTree()->size();
CassieSearch* searcher = new CassieSearch(indexer);
searcher->mode = mode;
// Allow 1 substitution for test
searcher->max_subst = max_subst;
searcher->max_indel = max_indel;
if(nmax > 0) {
ambiguity = true;
}
if(ambiguity) {
searcher->ambiguity = true;
if(nmax > 0) {
searcher->nmax = nmax;
}
}
searcher->search(pattern);
searcher->sort();
if(searcher->max_indel>0) {
searcher->removeDuplicates();
}
list matches = searcher->matches;
ofstream out_file;
out_file.open (out_file_name.c_str());
char* match_str;
int p_length = 0;
bool is_first = true;
if(format==1) {
out_file << "[";
}
for (std::list::iterator it = matches.begin(); it != matches.end(); it++) {
if((*it)->pos < min || (max>0 && (*it)->pos > max)) {
continue;
}
p_length = pattern.length();
DLOG(INFO) << "Match at: " << (*it)->pos << ", errors: " << (*it)->subst << "," << (*it)->in << "," << (*it)->del;
// For debug
ifstream seqstream (sequence, ios_base::in | ios_base::binary);
seqstream.seekg((*it)->pos, seqstream.beg);
match_str = new char[p_length+1]();
if(((*it)->in - (*it)->del) != 0) {
p_length = pattern.length() + (*it)->in - (*it)->del;
}
seqstream.read(match_str, p_length + 1);
match_str[p_length] = '\0';
//DLOG(INFO) << " => " << string(match_str);
if(format == 0) {
out_file << (*it)->pos << "\t" << p_length << "\t" << (*it)->subst << "\t" << (*it)->in+(*it)->del << "\t" << (*it)->in << "\t" << (*it)->del << "\n";
}
else {
if(is_first) {
is_first = false;
}
else { out_file << ","; }
out_file << "{\"position\": " << (*it)->pos << ",";
out_file << " \"length\": " << p_length << ",";
out_file << " \"substitution\": " << (*it)->subst << ",";
out_file << " \"indel\": " << (*it)->in+(*it)->del << ",";
out_file << " \"in\": " << (*it)->in << ",";
out_file << " \"del\": " << (*it)->del << "}";
}
delete[] match_str;
seqstream.close();
}
if(format==1) { out_file << "]\n"; }
out_file.close();
delete searcher;
delete indexer;
return 0;
}
cassiopee-c-1.0.3/src/cassiopee.cxx 0000664 0000000 0000000 00000072467 12510053312 0017204 0 ustar 00root root 0000000 0000000 // A simple program that computes the square root of a number
#include
#include
#include
#include
#include
#include
#include "Cassiopee.h"
using namespace std;
void CassiopeeUtils::transform_fasta(const string in, const string out) {
ifstream input( in.c_str() );
ofstream out_file ( out.c_str() );
bool first_seq = true;
for( string line; getline( input, line ); )
{
// Skip lines starting with '>'
if(line[0] == '>') {
if(first_seq) {
continue;
}
else {
break;
}
}
first_seq = false;
// write other lines
transform(line.begin(), line.end(), line.begin(), ::tolower);
out_file << line;
}
out_file.close();
}
Match::Match(): in(0),del(0), subst(0), pos(-1) {
}
TreeNode::TreeNode(char nc): c(nc), next_pos(-1), next_length(0) {
}
TreeNode::TreeNode(char nc, long pos): c(nc), next_pos(-1), next_length(0) {
}
TreeNode::TreeNode(): c(), next_pos(-1), next_length(0) {
}
const char Ambiguous::K_MATCH[] = { 'g', 't', 'u' };
const char Ambiguous::M_MATCH[] = { 'a', 'c' };
const char Ambiguous::R_MATCH[] = { 'a', 'g' };
const char Ambiguous::Y_MATCH[] = { 'c', 't', 'u' };
const char Ambiguous::S_MATCH[] = { 'c', 'g' };
const char Ambiguous::W_MATCH[] = { 'a', 't', 'u' };
const char Ambiguous::B_MATCH[] = { 'c', 'g', 't', 'u' };
const char Ambiguous::V_MATCH[] = { 'a', 'c', 'g' };
const char Ambiguous::H_MATCH[] = { 'a', 'c', 't', 'u' };
const char Ambiguous::D_MATCH[] = { 'a', 'g', 't', 'u' };
const char Ambiguous::N_MATCH[] = { 'a', 'c', 'g', 't', 'u' };
bool Ambiguous::ismatchequal(char a, const char b[],int len) {
for(int i=0;imatches.empty()) delete this->matches.front(), this->matches.pop_front();
delete match_limits;
}
bool CassieSearch::isequal(char a, char b) {
if(this->mode!=2 && (a=='n' || 'b'=='n')) {
// No N support for DNA/RNA
return false;
}
if(a==b) {
return true;
}
if(this->ambiguity && this->mode!=2) {
return Ambiguous::isequal(a,b);
}
else {
return a==b;
}
}
void CassieSearch::getMatchesFromNode(tree::iterator sib, const int nbSubsts, const int nbIn, const int nbDel) {
//LOG(INFO) << "getMatchesFromNode " << sib->c << "," << indexer->getTree()->depth(sib) << ":" << sib.number_of_children();
std::list positions = sib->positions;
#pragma omp critical(dataupdate)
for (std::list::iterator it = positions.begin(); it != positions.end(); it++) {
Match* match = new Match();
match->subst = nbSubsts;
match->in = nbIn;
match->del = nbDel;
//LOG(INFO) << "match1 at " << *it;
match->pos = *it;
this->matches.push_back(match);
//delete match;
}
if(sib.number_of_children() > 0) {
tree::iterator leaf_iterator = sib.begin();
while(leaf_iterator!= sib.end()) {
std::list positions = leaf_iterator->positions;
#pragma omp critical(dataupdate)
for (std::list::iterator it = positions.begin(); it != positions.end(); it++) {
//LOG(INFO) << "match2 at " << *it;
Match* match = new Match();
match->subst = nbSubsts;
match->in = nbIn;
match->del = nbDel;
match->pos = *it;
this->matches.push_back(match);
//delete match;
}
++leaf_iterator;
}
}
}
void CassieSearch::sort() {
this->matches.sort(per_position());
}
void CassieSearch::search(string suffixes[]) {
this->matches.clear();
#pragma omp parallel for if(use_openmp)
for (int it = 0; it < suffixes->size(); it++) {
this->search(suffixes[it],false);
}
}
void CassieSearch::search(string suffix) {
this->pattern_length = suffix.length();
this->search(suffix,true);
}
void CassieSearch::search(string suffix, bool clear) {
transform(suffix.begin(), suffix.end(), suffix.begin(), ::tolower);
if(clear) {
this->matches.clear();
}
tree* tr = this->indexer->getTree();
// Search from root
this->searchAtNode(suffix, 0, NULL, 0, 0, 0, 0);
}
bool CassieSearch::searchAtreduction(const string suffix, const tree::iterator sib, long counter, long tree_reducted_pos, int nbSubst, int nbIn, int nbDel, int nbN) {
//LOG(INFO) << "SEARCH AT REDUCTION";
char tree_char;
char suffix_char;
bool isequal = true;
while(counter < suffix.length() -1 && tree_reducted_pos < sib->next_length - 1 && isequal && sib->next_pos+tree_reducted_pos < this->indexer->seq_length - 1 ) {
counter++;
suffix_char = suffix[counter];
tree_reducted_pos++;
if(this->max_indel > 0 && nbIn+nbDel < this->max_indel) {
//LOG(INFO) << "CALL REDUCTION AGAIN";
this->searchAtreduction(suffix, sib, counter, tree_reducted_pos+1, nbSubst, nbIn+1, nbDel, nbN);
this->searchAtreduction(suffix, sib, counter+1, tree_reducted_pos, nbSubst, nbIn, nbDel+1, nbN);
}
tree_char = this->indexer->getCharAtSuffix(sib->next_pos+tree_reducted_pos);
//LOG(INFO) << "match " << suffix_char << " with " << tree_char << " at " << tree_reducted_pos << ", max=" << sib->next_length;
bool isequal = this->isequal(tree_char,suffix_char);
if(!isequal) {
// If DNA/RNA and tree matches a N, check on max consecutive N allowed
if(this->mode!=2 && tree_char == 'n') {
nbN++;
if(nbN <= this->nmax) {
isequal = true;
}
}
else {
nbN = 0;
}
}
if(!isequal && this->max_subst>0 && nbSubst < this->max_subst) {
// Check for substitutions
isequal = true;
nbSubst++;
}
}
if(isequal) {
if(counter == suffix.length() -1) {
this->getMatchesFromNode(sib, nbSubst, nbIn, nbDel);
return true;
}
else {
//LOG(INFO) << "full match but not complete, search childs";
// TODO complete match but suffix not over, should look at childs now
this->searchAtNode(suffix, counter+1, sib, NULL, nbSubst, nbIn, nbDel, nbN);
}
}
return false;
}
void CassieSearch::removeDuplicates() {
// TODO deletion of elements, as we manage pointers, list does not free memory for elements
matches.unique(CassieSearch::same_match);
}
void CassieSearch::searchAtNode(string suffix, const long suffix_pos, const tree::iterator root, int nbSubst, int nbIn, int nbDel, int nbN) {
this->searchAtNode(suffix, suffix_pos, root, NULL, nbSubst, nbIn, nbDel, nbN);
}
void CassieSearch::searchAtNode(string suffix, const long suffix_pos, const tree::iterator root, const tree::iterator start_node,int nbSubst, int nbIn, int nbDel, int nbN) {
//LOG(INFO) << "searchAtNode" << suffix_pos << ", " << nbSubst;
if(root!=NULL && root.number_of_children()==0) {
return;
}
tree* tr = this->indexer->getTree();
tree::iterator sib;
tree::iterator last_sibling;
tree::iterator parentnode = root;
if(root==NULL) {
if(start_node == NULL) {
sib = tr->begin();
}
else {
sib = start_node;
}
last_sibling = tr->end();
}
else {
if(start_node == NULL) {
sib = tr->begin(root);
}
else {
sib = start_node;
}
last_sibling = tr->end(root);
}
long counter = suffix_pos;
char tree_char = sib->c;
char suffix_char = suffix[counter];
while(sib != last_sibling && sib.node!=0) {
if(this->max_indel > 0 && nbIn+nbDel < this->max_indel) {
//LOG(INFO) << "Check for indel, cur= " << sib->c;
// Move on suffix, keep same base node
this->searchAtNode(suffix, counter+1, parentnode, sib, nbSubst, nbIn, nbDel+1, nbN);
// Go to childs, skip one element
tree::iterator start,end;
if(parentnode!=NULL) {
start = tr->begin(parentnode);
end = tr->end(parentnode);
}
else {
start = tr->begin();
end = tr->end();
}
while(start.node!=0 && start!=end) {
//LOG(INFO) << "skip " << start->c << "," << tr->depth(start);
this->searchAtNode(suffix, counter, start, nbSubst, nbIn+1, nbDel, nbN);
start = tr->next_sibling(start);
}
}
//LOG(INFO) << *sib << "," << *last_sibling;
//LOG(INFO) << "compare " << suffix_char << " with " << tree_char << ", " << counter << "," << tr->depth(sib);
bool isequal = this->isequal(tree_char,suffix_char);
tree::iterator next_sibling = sib;
while(this->mode!=2) {
next_sibling = tr->next_sibling(next_sibling);
if(next_sibling.node == 0) {
break;
}
// If DNA/RNA and tree matches a N, check on max consecutive N allowed
char next_tree_char = next_sibling->c;
if(next_tree_char == 'n') {
if(this->nmax>0 && nbN < this->nmax) {
if(counter == suffix.length()-1) {
// Last character, allow it
this->getMatchesFromNode(next_sibling, nbSubst, nbIn, nbDel);
}
else {
// Allow substitutions, so try child
this->searchAtNode(suffix, counter+1, next_sibling, nbSubst, nbIn, nbDel, nbN+1);
}
}
}
}
if(!isequal) {
// If DNA/RNA and tree matches a N, check on max consecutive N allowed
if(this->mode!=2 && tree_char == 'n') {
if(this->nmax>0 && nbN < this->nmax) {
if(counter == suffix.length()-1) {
// Last character, allow it
this->getMatchesFromNode(sib, nbSubst, nbIn, nbDel);
}
else {
// Allow substitutions, so try child
this->searchAtNode(suffix, counter+1, sib, nbSubst, nbIn, nbDel, nbN+1);
}
}
}
}
if(isequal) {
//LOG(INFO) << "compare " << suffix_char << " with " << tree_char << ", " << counter << "," << tr->depth(sib);
int nb_childs = sib.number_of_children();
//LOG(INFO) << "partial match, check below - " << nb_childs;
//LOG(INFO) << "filled? " << counter << ":" << suffix.length()-1;
if(counter == suffix.length()-1) {
// Exact match, no more char to parse
// Search leafs
this->getMatchesFromNode(sib, nbSubst, nbIn, nbDel);
if(this->max_subst>0 && nbSubst < this->max_subst) {
// If one last substitution is allowed, also check with remaining siblings
sib = tr->next_sibling(sib);
while(sib.node!=0) {
this->getMatchesFromNode(sib, nbSubst+1, nbIn, nbDel);
sib = tr->next_sibling(sib);
}
}
break;
}
else if(sib->next_pos>=0){
//LOG(INFO) << "next " << sib->next_pos << ", " << sib->next_length;
long tree_reducted_pos = -1;
bool matched = this->searchAtreduction(suffix, sib, counter, tree_reducted_pos, nbSubst, nbIn, nbDel, nbN);
break;
}
else if(nb_childs > 0) {
last_sibling = tr->end(sib);
parentnode = sib;
sib = tr->begin(sib);
//last_sibling = tr->end(sib);
tree_char = sib->c;
counter++;
suffix_char = suffix[counter];
}
else {
break;
}
}
else {
if(this->max_subst>0 && nbSubst < this->max_subst) {
if(counter == suffix.length()-1) {
// Last character, allow it
this->getMatchesFromNode(sib, nbSubst+1, nbIn, nbDel);
}
else {
// Allow substitutions, so try child
this->searchAtNode(suffix, counter+1, sib, nbSubst+1, nbIn, nbDel, nbN);
}
}
// anyway, test siblings
sib = tr->next_sibling(sib);
if(sib.node != 0) {
tree_char = sib->c;
}
else {
tree_char = '\0';
}
}
}
}
CassieIndexer::~CassieIndexer() {
if(this->seqstream) {
this->seqstream.close();
}
delete[] this->suffix;
}
CassieIndexer::CassieIndexer(const char* path): loaded_from_file(false),max_depth(0),do_reduction(false), filename(path), seqstream(path, ios_base::in | ios_base::binary), matches(), serialized_nodes(), MAX_SUFFIX(SUFFIX_CHUNK_SIZE),suffix_position(-1), suffix(NULL), max_index_depth(0)
{
// If we couldn't open the input file stream for reading
if (!this->seqstream)
{
// Print an error and exit
LOG(FATAL) << "Error: " << path << " could not be opened for reading!" ;
exit(1);
}
this->seqstream.seekg (0, this->seqstream.end);
this->seq_length = this->seqstream.tellg();
this->seqstream.seekg (0, this->seqstream.beg);
if (this->max_index_depth == 0) {
this->max_index_depth = this->seq_length-1;
}
}
char CassieIndexer::getCharAtSuffix(long pos) {
assert(pos < this->seq_length && pos>=0);
//LOG(INFO) << "getchar " << this->suffix_position << " < " << pos << " <= " << this->suffix_position + this->MAX_SUFFIX;
if(this->suffix_position >= 0 && pos >= this->suffix_position && pos< this->suffix_position + this->MAX_SUFFIX ) {
//LOG(INFO) << pos - this->suffix_position << ": " << this->suffix[pos - this->suffix_position];
return tolower(this->suffix[pos - this->suffix_position]);
}
else {
//LOG(INFO) << "Extract new suffix chunk at " << pos;
// Extract new suffix part
this->loadSuffix(pos);
return tolower(this->suffix[pos - this->suffix_position]);
}
}
char* CassieIndexer::loadSuffix(long pos) {
// Set initial position
this->suffix_position = pos;
assert(pos < this->seq_length);
long suffix_len = min(this->MAX_SUFFIX,this->seq_length - pos - 1);
//char* suffix = new char[suffix_len+1]();
delete[] this->suffix;
this->suffix = new char[suffix_len+1]();
this->seqstream.seekg(pos, this->seqstream.beg);
// Extract a suffix
this->seqstream.read(this->suffix, suffix_len);
*this->suffix = tolower(*this->suffix);
//LOG(INFO) << "Load suffix chunk "<< suffix;
//this->suffix = suffix;
return this->suffix;
}
void CassieIndexer::reset_suffix() {
this->suffix_position = -1;
}
void CassieIndexer::graph() {
this->graph(0);
}
void CassieIndexer::graph(int depth) {
ofstream myfile;
myfile.open ("cassiopee.dot");
int counter = 0;
myfile << "digraph cassiopee {\n";
myfile << "node" << 0 << " [label=\"head\"];\n";
this->graphNode(NULL, counter, myfile, depth);
myfile << "}\n";
myfile.close();
}
long CassieIndexer::graphNode(tree::iterator node, long parent, ofstream& myfile, int maxdepth) {
tree::iterator first;
tree::iterator last;
if(node == NULL) {
first = tr.begin();
last = tr.end();
}
else {
first= node.begin();
last= node.end();
}
long child = parent+1;
while(first!=last && first.node!=0) {
//char* next_chars = new char[first->next_length];
//this->seqstream.seekg(first->next_pos, this->seqstream.beg);
//this->seqstream.read(next_chars, first->next_length);
myfile << "node" << parent << " -> " << "node" << child << ";\n";
myfile << "node" << child << " [label=\"" << first->c << "-" << first->next_length << "\"];\n";
if(first.number_of_children()>0 && (maxdepth==0 || tr.depth(first) < maxdepth)) {
child = this->graphNode(first, child, myfile, maxdepth);
}
child++;
first = tr.next_sibling(first);
}
return child;
}
void CassieIndexer::index() {
long max_depth = 0;
string index_meta_file = string(this->filename)+".cass.meta";
ifstream metafile (index_meta_file.c_str());
if (metafile.is_open()) {
string line;
getline(metafile, line);
max_depth = atol(line.c_str());
metafile.close();
}
LOG(INFO) << "Existing index for max depth = " << max_depth << std::endl;
if (max_depth >= this->max_index_depth) {
string index_file = string(this->filename)+".cass.idx";
if (ifstream(index_file.c_str()))
{
LOG(INFO) << "Index file exists, loading it" << std::endl;
this->load();
this->loaded_from_file = true;
return;
}
}
if(!(this->tr).empty()) {
DLOG(INFO) << "Indexed already filled";
return;
}
DLOG(INFO) << "Indexing " << this->filename ;
for (long i=0; iseq_length-1; i++) {
this->filltree(i);
}
}
bool CassieIndexer::index_loaded_from_file() {
return this->loaded_from_file;
}
void CassieIndexer::save() {
if((this->tr).empty()) {
cerr << "Index is empty" << endl;
}
tree::iterator node = this->tr.begin();
tree::iterator end = this->tr.end();
int depth;
while(node!=end) {
depth = tr.depth(node);
// write class instance to archive
TreeNode ar_node = node.node->data;
this->serialized_nodes.push_back(ar_node);
++node;
// If we go up, we have finished this level
if(tr.depth(node) <= depth ) {
for(int i = tr.depth(node);i <= depth; i++){
TreeNode end_node = TreeNode('0');
this->serialized_nodes.push_back(end_node);
}
}
}
//DLOG(INFO) << "Number of nodes: " << this->serialized_nodes.size();
LOG(INFO) << "Maximum index depth: " << this->max_index_depth << std::endl;
string index_meta_file = string(this->filename)+".cass.meta";
ofstream metafile;
metafile.open (index_meta_file.c_str());
metafile << this->max_index_depth;
metafile.close();
string index_file = string(this->filename)+".cass.idx";
ofstream ofs(index_file.c_str());
boost::archive::text_oarchive oa(ofs);
oa << this->serialized_nodes;
ofs.close();
this->serialized_nodes.clear();
}
void CassieIndexer::load() {
// create and open an archive for input
string index_file = string(this->filename)+".cass.idx";
ifstream ifs(index_file.c_str());
boost::archive::text_iarchive ia(ifs);
tree::iterator sib;
this->tr.clear();
sib = this->tr.begin();
int depth = 0;
ia >> this->serialized_nodes;
for (std::list::const_iterator iterator = this->serialized_nodes.begin(), end = this->serialized_nodes.end(); iterator != end; ++iterator) {
if(iterator->c != '0') {
if(depth==0) {
//cout << "insert child";
sib = this->tr.insert(this->tr.begin(), *iterator);
}
else {
//cout << "append child";
sib = this->tr.append_child(sib, *iterator);
}
depth++;
}
else {
depth--;
// Should be back to parent
sib = sib.node->parent;
}
}
this->serialized_nodes.clear();
DLOG(INFO) << "Loaded " << this->getTree()->size() << " nodes";
// archive and stream closed when destructors are called
}
string CassieIndexer::getSuffix(long pos) {
char* suffix;
this->seqstream.seekg(pos);
// Get the rest of the line and print it
this->seqstream.getline(suffix,this->seq_length-1);
*suffix = tolower(*suffix);
return suffix;
}
void CassieIndexer::fillTreeWithSuffix(long suffix_pos, long pos) {
tree::iterator sib;
char node_char = this->getCharAtSuffix(pos+suffix_pos);
//long suffix_len = this->seq_length - (pos+suffix_pos) -1;
// OSALLOU
long suffix_len = min(this->max_index_depth, this->seq_length - (pos+suffix_pos) -1);
TreeNode* node = new TreeNode(node_char);
if(suffix_len==1) {
std::list::iterator end = node->positions.end();
node->positions.insert(end, pos);
}
if(this->tr.begin().number_of_children()==0) {
sib = this->tr.insert(this->tr.begin(), *node);
//LOG(INFO) << "add first head element";
}
else {
//LOG(INFO) << "insert new head element";
sib = this->tr.insert_after(this->tr.begin(),*node);
}
delete node;
if(suffix_len==1) {
return;
}
this->fillTreeWithSuffix(sib, suffix_pos+1, pos);
}
void CassieIndexer::fillTreeWithSuffix(tree::iterator sib, long suffix_pos, long pos) {
//long suffix_len = this->seq_length - pos -1 ;
//OSALLOU
long suffix_len = min(this->max_index_depth, this->seq_length - pos -1);
for(long i=suffix_pos;igetCharAtSuffix(pos+i);
if(node_char == '\0') {
//LOG(INFO) << "break";
break;
}
//LOG(INFO) << "add char " << node_char << " from pos " << pos << "to" << pos + suffix_len << " at " << pos+i << ", l= " << suffix_len;
TreeNode* node = new TreeNode(node_char);
if(i==suffix_len-1) {
// If last node, append position of suffix
//LOG(INFO) << "add position to node " << pos;
node->positions.push_back(pos);
}
sib = this->tr.append_child(sib,*node);
delete node;
if(this->do_reduction) {
sib->next_pos = pos + i + 1;
sib->next_length = suffix_len - 1;
//LOG(INFO) << "add position to node " << pos;
//LOG(INFO) << "next_pos " << sib->next_pos;
//LOG(INFO) << "next_length " << sib->next_length;
if(i!=suffix_len-1) {
// Position already added, this is a special case
sib->positions.push_back(pos);
}
//LOG(INFO) << "apply reduction: " << sib->next_pos << "," << sib->next_length;
break;
}
}
}
tree* CassieIndexer::getTree() {
return &(this->tr);
}
void CassieIndexer::filltree(long pos) {
tree::iterator sib;
tree::iterator last_sibling;
tree::iterator place_to_insert;
//long suffix_len = this->seq_length - pos - 1;
// OSALLOU
long suffix_len = min(this->max_index_depth, this->seq_length - pos - 1);
//LOG(INFO) << "new suffix " << pos << " l= " << suffix_len;
sib = this->tr.begin();
place_to_insert = this->tr.end();
last_sibling = this->tr.end();
bool match = false;
bool nomore = false;
bool head = true;
long counter = 0;
char tree_char = sib->c;
/*
* In case of tree reduction, position of char in next_pos characters
*/
long tree_reducted_pos = -1;
while(!match && !nomore) {
char suffix_char = this->getCharAtSuffix(pos+counter);
//LOG(INFO) << "compare " << suffix_char << " with " << tree_char << " at " << pos+counter << ", d: " << this->tr.depth(sib);
if(tree_char == suffix_char) {
head = false;
int nb_childs = sib.number_of_children();
//LOG(INFO) << "found match, check below, " << "node children " << nb_childs;
//LOG(INFO) << "counter: " << counter << ", suffix: " << strlen(suffix);
if(counter==suffix_len-1 && sib->next_pos<0) {
//LOG(INFO) << "no more suffix ";
match = true;
tree_reducted_pos = -1;
//LOG(INFO) << "suffix " << suffix << " at " << pos << ", d=" << tr.depth(sib);
sib->positions.push_back(pos);
}
else if(sib->next_pos>=0 && tree_reducted_pos < sib->next_length) {
while(tree_reducted_pos < sib->next_length && suffix_char == tree_char) {
if(counter == suffix_len - 1) {
// Match before parsing all chars
// Insert a node here
match = true;
this->seqstream.seekg(sib->next_pos + tree_reducted_pos + 1, this->seqstream.beg);
this->seqstream.read(&tree_char, 1);
tree_char = tolower(tree_char);
TreeNode * tmp_node = new TreeNode(tree_char);
tmp_node->next_length = sib->next_length - tree_reducted_pos - 2;
tmp_node->next_pos = sib->next_pos + tree_reducted_pos + 1;
sib->next_length = tree_reducted_pos ;
if(sib->next_length<=0) {
sib->next_pos = -1;
sib->next_length = 0;
}
if(tmp_node->next_length<=0) {
tmp_node->next_pos = -1;
tmp_node->next_length = 0;
}
tree::iterator old = sib;
if(sib.number_of_children()>0) {
LOG(INFO) << "insert node between children";
// Move children to new node
tree_node_ *first = sib.node->first_child;
tree_node_ *last = sib.node->last_child;
sib.node->first_child=0;
sib.node->last_child=0;
sib = this->tr.append_child(sib, *tmp_node);
sib.node->first_child = first;
sib.node->last_child = last;
sib.node->first_child->parent=sib.node;
sib.node->last_child->parent=sib.node;
}
else {
sib = this->tr.append_child(sib, *tmp_node);
}
for (std::list::iterator it = old->positions.begin(); it != old->positions.end(); it++) {
sib->positions.push_back(*it);
}
old->positions.clear();
old->positions.push_back(pos);
delete tmp_node;
tree_reducted_pos = -1;
break;
}
tree_reducted_pos++;
counter++;
suffix_char = this->getCharAtSuffix(pos+counter);
// Tree reduction case and refer to chars in sequence
this->seqstream.seekg(sib->next_pos+tree_reducted_pos, this->seqstream.beg);
// Extract a suffix
this->seqstream.read(&tree_char, 1);
tree_char = tolower(tree_char);
//LOG(INFO) << "take next char in reduction: " << tree_char << " at " << sib->next_pos+tree_reducted_pos;
}
place_to_insert = sib;
break;
}
else if(nb_childs >0 && (this->max_depth==0 || tr.depth(sib) < this->max_depth)) {
//LOG(INFO) << "check children";
// Continue parsing
// reset anyway tree_reducted_pos
tree_reducted_pos = -1;
// Look at children now
sib = tr.begin(sib);
tree_char = sib->c;
counter++;
}
else {
//LOG(INFO) << "no more child, fill with suffix";
match = true;
tree_reducted_pos = -1;
// Last matching node, fill the rest of the node with current suffix
this->fillTreeWithSuffix(sib, counter+1, pos);
//LOG(INFO) << "suffix " << suffix << " at " << pos;
}
}
else {
tree_reducted_pos = -1;
// Switch to next node
//LOG(INFO) << "no match, compare sibling " << this->tr.depth(sib);
last_sibling = this->tr.end(sib);
place_to_insert = sib;
sib = tr.next_sibling(sib);
if(sib.node==0) {
nomore = true;
//LOG(INFO) << "no more";
}
else {
tree_char = sib->c;
}
}
}
if(!match) {
char node_char = this->getCharAtSuffix(pos+counter);
//char node_char = suffix[counter];
if(head) {
//LOG(INFO) << "No match found, add new node " << node_char << " at head";
this->fillTreeWithSuffix(counter, pos);
}
else {
//LOG(INFO) << "No match found, add new node " << node_char << " in tree at " << tr.depth(place_to_insert);
if(tree_reducted_pos > -1) {
// Add a new child matching last matched character
this->seqstream.seekg(place_to_insert->next_pos + tree_reducted_pos, this->seqstream.beg);
this->seqstream.read(&tree_char, 1);
tree_char = tolower(tree_char);
//LOG(INFO) << "add new node " << tree_char << ":" << place_to_insert->next_pos << ":" << tree_reducted_pos << " in tree at " << tr.depth(place_to_insert) << "," << place_to_insert->c;
//LOG(INFO) <<"insert "<::iterator old = place_to_insert;
tmp_node->next_length = place_to_insert->next_length - tree_reducted_pos - 2;
tmp_node->next_pos = place_to_insert->next_pos + tree_reducted_pos + 1;
place_to_insert->next_length = tree_reducted_pos ;
if(place_to_insert->next_length<=0) {
place_to_insert->next_pos = -1;
place_to_insert->next_length = 0;
}
if(tmp_node->next_length<=0) {
tmp_node->next_pos = -1;
tmp_node->next_length = 0;
}
if(place_to_insert.number_of_children()>0) {
//LOG(INFO) << "- insert node between children";
// Move children to new node
tree_node_ *first = place_to_insert.node->first_child;
tree_node_ *last = place_to_insert.node->last_child;
place_to_insert.node->first_child=0;
place_to_insert.node->last_child=0;
place_to_insert = this->tr.append_child(place_to_insert, *tmp_node);
place_to_insert.node->first_child = first;
place_to_insert.node->last_child = last;
place_to_insert.node->first_child->parent=place_to_insert.node;
place_to_insert.node->last_child->parent=place_to_insert.node;
}
else {
place_to_insert = this->tr.append_child(place_to_insert, *tmp_node);
}
//place_to_insert = this->tr.append_child(place_to_insert, *tmp_node);
for (std::list::iterator it = old->positions.begin(); it != old->positions.end(); it++) {
place_to_insert->positions.push_back(*it);
}
old->positions.clear();
delete tmp_node;
}
tree_reducted_pos = -1;
TreeNode* node = new TreeNode(node_char);
place_to_insert = this->tr.insert_after(place_to_insert, *node);
if(counter==suffix_len-1) {
// If last node, append position of suffix
place_to_insert->positions.push_back(pos);
}
else {
this->fillTreeWithSuffix(place_to_insert, counter+1, pos);
}
delete node;
}
//LOG(INFO) << "suffix " << suffix << " at " << pos;
}
}
cassiopee-c-1.0.3/src/knife.cxx 0000664 0000000 0000000 00000002640 12510053312 0016307 0 ustar 00root root 0000000 0000000 // A simple program that computes the square root of a number
#include
#include
#include
#include
#include
#include
#include "CassiopeeConfig.h"
#include "Cassiopee.h"
using namespace std;
void showUsage() {
fprintf(stdout,"Usage:\n");
fprintf(stdout,"\t-s: sequence to convert\n");
fprintf(stdout,"\t-o: output file\n");
fprintf(stdout,"\t-v: show version\n");
fprintf(stdout,"\t-h: show this message\n");
}
void showVersion() {
fprintf(stdout,"%s Version %d.%d\n",
"Cassiopee",
Cassiopee_VERSION_MAJOR,
Cassiopee_VERSION_MINOR);
}
int main (int argc, char *argv[])
{
if (argc == 1) {
showVersion();
showUsage();
return 1;
}
int c;
string sequence="";
string out="";
while ((c = getopt (argc, argv, "s:o:vh")) != -1)
switch (c)
{
case 's':
sequence = string(optarg);
break;
case 'o':
out = string(optarg);
break;
case 'h':
showUsage();
return 0;
case 'v':
showVersion();
return 0;
default:
abort ();
}
if(sequence.empty()||out.empty()) {
fprintf (stderr,
"Sequence file or output file not specified in command line.\n");
return 1;
}
CassiopeeUtils::transform_fasta(sequence, out);
return 0;
}
cassiopee-c-1.0.3/src/tree/ 0000775 0000000 0000000 00000000000 12510053312 0015424 5 ustar 00root root 0000000 0000000 cassiopee-c-1.0.3/src/tree/tree.hh 0000664 0000000 0000000 00000242133 12510053312 0016711 0 ustar 00root root 0000000 0000000
// STL-like templated tree class.
//
// Copyright (C) 2001-2011 Kasper Peeters
// Distributed under the GNU General Public License version 3.
//
// When used together with the htmlcxx library to create
// HTML::Node template instances, the GNU Lesser General Public
// version 2 applies. Special permission to use tree.hh under
// the LGPL for other projects can be requested from the author.
/** \mainpage tree.hh
\author Kasper Peeters
\version 2.81
\date 23-Aug-2011
\see http://tree.phi-sci.com/
\see http://tree.phi-sci.com/ChangeLog
The tree.hh library for C++ provides an STL-like container class
for n-ary trees, templated over the data stored at the
nodes. Various types of iterators are provided (post-order,
pre-order, and others). Where possible the access methods are
compatible with the STL or alternative algorithms are
available.
*/
#ifndef tree_hh_
#define tree_hh_
#include
#include
#include
#include
#include
#include
#include
#include
/// A node in the tree, combining links to other nodes as well as the actual data.
template
class tree_node_ { // size: 5*4=20 bytes (on 32 bit arch), can be reduced by 8.
public:
tree_node_();
tree_node_(const T&);
tree_node_ *parent;
tree_node_ *first_child, *last_child;
tree_node_ *prev_sibling, *next_sibling;
T data;
}; // __attribute__((packed));
template
tree_node_::tree_node_()
: parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0)
{
}
template
tree_node_::tree_node_(const T& val)
: parent(0), first_child(0), last_child(0), prev_sibling(0), next_sibling(0), data(val)
{
}
template > >
class tree {
protected:
typedef tree_node_ tree_node;
public:
/// Value of the data stored at a node.
typedef T value_type;
class iterator_base;
class pre_order_iterator;
class post_order_iterator;
class sibling_iterator;
class leaf_iterator;
tree();
tree(const T&);
tree(const iterator_base&);
tree(const tree&);
~tree();
tree& operator=(const tree&);
/// Base class for iterators, only pointers stored, no traversal logic.
#ifdef __SGI_STL_PORT
class iterator_base : public stlport::bidirectional_iterator {
#else
class iterator_base {
#endif
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
iterator_base();
iterator_base(tree_node *);
T& operator*() const;
T* operator->() const;
/// When called, the next increment/decrement skips children of this node.
void skip_children();
void skip_children(bool skip);
/// Number of children of the node pointed to by the iterator.
unsigned int number_of_children() const;
sibling_iterator begin() const;
sibling_iterator end() const;
tree_node *node;
protected:
bool skip_current_children_;
};
/// Depth-first iterator, first accessing the node, then its children.
class pre_order_iterator : public iterator_base {
public:
pre_order_iterator();
pre_order_iterator(tree_node *);
pre_order_iterator(const iterator_base&);
pre_order_iterator(const sibling_iterator&);
bool operator==(const pre_order_iterator&) const;
bool operator!=(const pre_order_iterator&) const;
pre_order_iterator& operator++();
pre_order_iterator& operator--();
pre_order_iterator operator++(int);
pre_order_iterator operator--(int);
pre_order_iterator& operator+=(unsigned int);
pre_order_iterator& operator-=(unsigned int);
};
/// Depth-first iterator, first accessing the children, then the node itself.
class post_order_iterator : public iterator_base {
public:
post_order_iterator();
post_order_iterator(tree_node *);
post_order_iterator(const iterator_base&);
post_order_iterator(const sibling_iterator&);
bool operator==(const post_order_iterator&) const;
bool operator!=(const post_order_iterator&) const;
post_order_iterator& operator++();
post_order_iterator& operator--();
post_order_iterator operator++(int);
post_order_iterator operator--(int);
post_order_iterator& operator+=(unsigned int);
post_order_iterator& operator-=(unsigned int);
/// Set iterator to the first child as deep as possible down the tree.
void descend_all();
};
/// Breadth-first iterator, using a queue
class breadth_first_queued_iterator : public iterator_base {
public:
breadth_first_queued_iterator();
breadth_first_queued_iterator(tree_node *);
breadth_first_queued_iterator(const iterator_base&);
bool operator==(const breadth_first_queued_iterator&) const;
bool operator!=(const breadth_first_queued_iterator&) const;
breadth_first_queued_iterator& operator++();
breadth_first_queued_iterator operator++(int);
breadth_first_queued_iterator& operator+=(unsigned int);
private:
std::queue traversal_queue;
};
/// The default iterator types throughout the tree class.
typedef pre_order_iterator iterator;
typedef breadth_first_queued_iterator breadth_first_iterator;
/// Iterator which traverses only the nodes at a given depth from the root.
class fixed_depth_iterator : public iterator_base {
public:
fixed_depth_iterator();
fixed_depth_iterator(tree_node *);
fixed_depth_iterator(const iterator_base&);
fixed_depth_iterator(const sibling_iterator&);
fixed_depth_iterator(const fixed_depth_iterator&);
bool operator==(const fixed_depth_iterator&) const;
bool operator!=(const fixed_depth_iterator&) const;
fixed_depth_iterator& operator++();
fixed_depth_iterator& operator--();
fixed_depth_iterator operator++(int);
fixed_depth_iterator operator--(int);
fixed_depth_iterator& operator+=(unsigned int);
fixed_depth_iterator& operator-=(unsigned int);
tree_node *top_node;
};
/// Iterator which traverses only the nodes which are siblings of each other.
class sibling_iterator : public iterator_base {
public:
sibling_iterator();
sibling_iterator(tree_node *);
sibling_iterator(const sibling_iterator&);
sibling_iterator(const iterator_base&);
bool operator==(const sibling_iterator&) const;
bool operator!=(const sibling_iterator&) const;
sibling_iterator& operator++();
sibling_iterator& operator--();
sibling_iterator operator++(int);
sibling_iterator operator--(int);
sibling_iterator& operator+=(unsigned int);
sibling_iterator& operator-=(unsigned int);
tree_node *range_first() const;
tree_node *range_last() const;
tree_node *parent_;
private:
void set_parent_();
};
/// Iterator which traverses only the leaves.
class leaf_iterator : public iterator_base {
public:
leaf_iterator();
leaf_iterator(tree_node *, tree_node *top=0);
leaf_iterator(const sibling_iterator&);
leaf_iterator(const iterator_base&);
bool operator==(const leaf_iterator&) const;
bool operator!=(const leaf_iterator&) const;
leaf_iterator& operator++();
leaf_iterator& operator--();
leaf_iterator operator++(int);
leaf_iterator operator--(int);
leaf_iterator& operator+=(unsigned int);
leaf_iterator& operator-=(unsigned int);
private:
tree_node *top_node;
};
/// Return iterator to the beginning of the tree.
inline pre_order_iterator begin() const;
/// Return iterator to the end of the tree.
inline pre_order_iterator end() const;
/// Return post-order iterator to the beginning of the tree.
post_order_iterator begin_post() const;
/// Return post-order end iterator of the tree.
post_order_iterator end_post() const;
/// Return fixed-depth iterator to the first node at a given depth from the given iterator.
fixed_depth_iterator begin_fixed(const iterator_base&, unsigned int) const;
/// Return fixed-depth end iterator.
fixed_depth_iterator end_fixed(const iterator_base&, unsigned int) const;
/// Return breadth-first iterator to the first node at a given depth.
breadth_first_queued_iterator begin_breadth_first() const;
/// Return breadth-first end iterator.
breadth_first_queued_iterator end_breadth_first() const;
/// Return sibling iterator to the first child of given node.
sibling_iterator begin(const iterator_base&) const;
/// Return sibling end iterator for children of given node.
sibling_iterator end(const iterator_base&) const;
/// Return leaf iterator to the first leaf of the tree.
leaf_iterator begin_leaf() const;
/// Return leaf end iterator for entire tree.
leaf_iterator end_leaf() const;
/// Return leaf iterator to the first leaf of the subtree at the given node.
leaf_iterator begin_leaf(const iterator_base& top) const;
/// Return leaf end iterator for the subtree at the given node.
leaf_iterator end_leaf(const iterator_base& top) const;
/// Return iterator to the parent of a node.
template static iter parent(iter);
/// Return iterator to the previous sibling of a node.
template iter previous_sibling(iter) const;
/// Return iterator to the next sibling of a node.
template iter next_sibling(iter) const;
/// Return iterator to the next node at a given depth.
template iter next_at_same_depth(iter) const;
/// Erase all nodes of the tree.
void clear();
/// Erase element at position pointed to by iterator, return incremented iterator.
template iter erase(iter);
/// Erase all children of the node pointed to by iterator.
void erase_children(const iterator_base&);
/// Insert empty node as last/first child of node pointed to by position.
template iter append_child(iter position);
template iter prepend_child(iter position);
/// Insert node as last/first child of node pointed to by position.
template iter append_child(iter position, const T& x);
template iter prepend_child(iter position, const T& x);
/// Append the node (plus its children) at other_position as last/first child of position.
template iter append_child(iter position, iter other_position);
template iter prepend_child(iter position, iter other_position);
/// Append the nodes in the from-to range (plus their children) as last/first children of position.
template iter append_children(iter position, sibling_iterator from, sibling_iterator to);
template iter prepend_children(iter position, sibling_iterator from, sibling_iterator to);
/// Short-hand to insert topmost node in otherwise empty tree.
pre_order_iterator set_head(const T& x);
/// Insert node as previous sibling of node pointed to by position.
template iter insert(iter position, const T& x);
/// Specialisation of previous member.
sibling_iterator insert(sibling_iterator position, const T& x);
/// Insert node (with children) pointed to by subtree as previous sibling of node pointed to by position.
template iter insert_subtree(iter position, const iterator_base& subtree);
/// Insert node as next sibling of node pointed to by position.
template iter insert_after(iter position, const T& x);
/// Insert node (with children) pointed to by subtree as next sibling of node pointed to by position.
template iter insert_subtree_after(iter position, const iterator_base& subtree);
/// Replace node at 'position' with other node (keeping same children); 'position' becomes invalid.
template iter replace(iter position, const T& x);
/// Replace node at 'position' with subtree starting at 'from' (do not erase subtree at 'from'); see above.
template iter replace(iter position, const iterator_base& from);
/// Replace string of siblings (plus their children) with copy of a new string (with children); see above
sibling_iterator replace(sibling_iterator orig_begin, sibling_iterator orig_end,
sibling_iterator new_begin, sibling_iterator new_end);
/// Move all children of node at 'position' to be siblings, returns position.
template iter flatten(iter position);
/// Move nodes in range to be children of 'position'.
template iter reparent(iter position, sibling_iterator begin, sibling_iterator end);
/// Move all child nodes of 'from' to be children of 'position'.
template iter reparent(iter position, iter from);
/// Replace node with a new node, making the old node a child of the new node.
template iter wrap(iter position, const T& x);
/// Move 'source' node (plus its children) to become the next sibling of 'target'.
template iter move_after(iter target, iter source);
/// Move 'source' node (plus its children) to become the previous sibling of 'target'.
template iter move_before(iter target, iter source);
sibling_iterator move_before(sibling_iterator target, sibling_iterator source);
/// Move 'source' node (plus its children) to become the node at 'target' (erasing the node at 'target').
template iter move_ontop(iter target, iter source);
/// Merge with other tree, creating new branches and leaves only if they are not already present.
void merge(sibling_iterator, sibling_iterator, sibling_iterator, sibling_iterator,
bool duplicate_leaves=false);
/// Sort (std::sort only moves values of nodes, this one moves children as well).
void sort(sibling_iterator from, sibling_iterator to, bool deep=false);
template
void sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep=false);
/// Compare two ranges of nodes (compares nodes as well as tree structure).
template
bool equal(const iter& one, const iter& two, const iter& three) const;
template
bool equal(const iter& one, const iter& two, const iter& three, BinaryPredicate) const;
template
bool equal_subtree(const iter& one, const iter& two) const;
template
bool equal_subtree(const iter& one, const iter& two, BinaryPredicate) const;
/// Extract a new tree formed by the range of siblings plus all their children.
tree subtree(sibling_iterator from, sibling_iterator to) const;
void subtree(tree&, sibling_iterator from, sibling_iterator to) const;
/// Exchange the node (plus subtree) with its sibling node (do nothing if no sibling present).
void swap(sibling_iterator it);
/// Exchange two nodes (plus subtrees)
void swap(iterator, iterator);
/// Count the total number of nodes.
size_t size() const;
/// Count the total number of nodes below the indicated node (plus one).
size_t size(const iterator_base&) const;
/// Check if tree is empty.
bool empty() const;
/// Compute the depth to the root or to a fixed other iterator.
static int depth(const iterator_base&);
static int depth(const iterator_base&, const iterator_base&);
/// Determine the maximal depth of the tree. An empty tree has max_depth=-1.
int max_depth() const;
/// Determine the maximal depth of the tree with top node at the given position.
int max_depth(const iterator_base&) const;
/// Count the number of children of node at position.
static unsigned int number_of_children(const iterator_base&);
/// Count the number of siblings (left and right) of node at iterator. Total nodes at this level is +1.
unsigned int number_of_siblings(const iterator_base&) const;
/// Determine whether node at position is in the subtrees with root in the range.
bool is_in_subtree(const iterator_base& position, const iterator_base& begin,
const iterator_base& end) const;
/// Determine whether the iterator is an 'end' iterator and thus not actually pointing to a node.
bool is_valid(const iterator_base&) const;
/// Find the lowest common ancestor of two nodes, that is, the deepest node such that
/// both nodes are descendants of it.
iterator lowest_common_ancestor(const iterator_base&, const iterator_base &) const;
/// Determine the index of a node in the range of siblings to which it belongs.
unsigned int index(sibling_iterator it) const;
/// Inverse of 'index': return the n-th child of the node at position.
static sibling_iterator child(const iterator_base& position, unsigned int);
/// Return iterator to the sibling indicated by index
sibling_iterator sibling(const iterator_base& position, unsigned int);
/// For debugging only: verify internal consistency by inspecting all pointers in the tree
/// (which will also trigger a valgrind error in case something got corrupted).
void debug_verify_consistency() const;
/// Comparator class for iterators (compares pointer values; why doesn't this work automatically?)
class iterator_base_less {
public:
bool operator()(const typename tree::iterator_base& one,
const typename tree::iterator_base& two) const
{
return one.node < two.node;
}
};
tree_node *head, *feet; // head/feet are always dummy; if an iterator points to them it is invalid
private:
tree_node_allocator alloc_;
void head_initialise_();
void copy_(const tree& other);
/// Comparator class for two nodes of a tree (used for sorting and searching).
template
class compare_nodes {
public:
compare_nodes(StrictWeakOrdering comp) : comp_(comp) {};
bool operator()(const tree_node *a, const tree_node *b)
{
return comp_(a->data, b->data);
}
private:
StrictWeakOrdering comp_;
};
};
//template
//class iterator_base_less {
// public:
// bool operator()(const typename tree::iterator_base& one,
// const typename tree::iterator_base& two) const
// {
// txtout << "operatorclass<" << one.node < two.node << std::endl;
// return one.node < two.node;
// }
//};
// template
// bool operator<(const typename tree::iterator& one,
// const typename tree::iterator& two)
// {
// txtout << "operator< " << one.node < two.node << std::endl;
// if(one.node < two.node) return true;
// return false;
// }
//
// template
// bool operator==(const typename tree::iterator& one,
// const typename tree::iterator& two)
// {
// txtout << "operator== " << one.node == two.node << std::endl;
// if(one.node == two.node) return true;
// return false;
// }
//
// template
// bool operator>(const typename tree::iterator_base& one,
// const typename tree::iterator_base& two)
// {
// txtout << "operator> " << one.node < two.node << std::endl;
// if(one.node > two.node) return true;
// return false;
// }
// Tree
template
tree::tree()
{
head_initialise_();
}
template
tree::tree(const T& x)
{
head_initialise_();
set_head(x);
}
template
tree::tree(const iterator_base& other)
{
head_initialise_();
set_head((*other));
replace(begin(), other);
}
template
tree::~tree()
{
clear();
alloc_.destroy(head);
alloc_.destroy(feet);
alloc_.deallocate(head,1);
alloc_.deallocate(feet,1);
}
template
void tree::head_initialise_()
{
head = alloc_.allocate(1,0); // MSVC does not have default second argument
feet = alloc_.allocate(1,0);
alloc_.construct(head, tree_node_());
alloc_.construct(feet, tree_node_());
head->parent=0;
head->first_child=0;
head->last_child=0;
head->prev_sibling=0; //head;
head->next_sibling=feet; //head;
feet->parent=0;
feet->first_child=0;
feet->last_child=0;
feet->prev_sibling=head;
feet->next_sibling=0;
}
template
tree& tree::operator=(const tree& other)
{
if(this != &other)
copy_(other);
return *this;
}
template
tree::tree(const tree& other)
{
head_initialise_();
copy_(other);
}
template
void tree::copy_(const tree& other)
{
clear();
pre_order_iterator it=other.begin(), to=begin();
while(it!=other.end()) {
to=insert(to, (*it));
it.skip_children();
++it;
}
to=begin();
it=other.begin();
while(it!=other.end()) {
to=replace(to, it);
to.skip_children();
it.skip_children();
++to;
++it;
}
}
template
void tree::clear()
{
if(head)
while(head->next_sibling!=feet)
erase(pre_order_iterator(head->next_sibling));
}
template
void tree::erase_children(const iterator_base& it)
{
// std::cout << "erase_children " << it.node << std::endl;
if(it.node==0) return;
tree_node *cur=it.node->first_child;
tree_node *prev=0;
while(cur!=0) {
prev=cur;
cur=cur->next_sibling;
erase_children(pre_order_iterator(prev));
// kp::destructor(&prev->data);
alloc_.destroy(prev);
alloc_.deallocate(prev,1);
}
it.node->first_child=0;
it.node->last_child=0;
// std::cout << "exit" << std::endl;
}
template
template
iter tree::erase(iter it)
{
tree_node *cur=it.node;
assert(cur!=head);
iter ret=it;
ret.skip_children();
++ret;
erase_children(it);
if(cur->prev_sibling==0) {
cur->parent->first_child=cur->next_sibling;
}
else {
cur->prev_sibling->next_sibling=cur->next_sibling;
}
if(cur->next_sibling==0) {
cur->parent->last_child=cur->prev_sibling;
}
else {
cur->next_sibling->prev_sibling=cur->prev_sibling;
}
// kp::destructor(&cur->data);
alloc_.destroy(cur);
alloc_.deallocate(cur,1);
return ret;
}
template
typename tree::pre_order_iterator tree::begin() const
{
return pre_order_iterator(head->next_sibling);
}
template
typename tree::pre_order_iterator tree::end() const
{
return pre_order_iterator(feet);
}
template
typename tree::breadth_first_queued_iterator tree::begin_breadth_first() const
{
return breadth_first_queued_iterator(head->next_sibling);
}
template
typename tree::breadth_first_queued_iterator tree::end_breadth_first() const
{
return breadth_first_queued_iterator();
}
template
typename tree::post_order_iterator tree::begin_post() const
{
tree_node *tmp=head->next_sibling;
if(tmp!=feet) {
while(tmp->first_child)
tmp=tmp->first_child;
}
return post_order_iterator(tmp);
}
template
typename tree::post_order_iterator tree::end_post() const
{
return post_order_iterator(feet);
}
template
typename tree::fixed_depth_iterator tree::begin_fixed(const iterator_base& pos, unsigned int dp) const
{
typename tree::fixed_depth_iterator ret;
ret.top_node=pos.node;
tree_node *tmp=pos.node;
unsigned int curdepth=0;
while(curdepthfirst_child==0) {
if(tmp->next_sibling==0) {
// try to walk up and then right again
do {
if(tmp==ret.top_node)
throw std::range_error("tree: begin_fixed out of range");
tmp=tmp->parent;
if(tmp==0)
throw std::range_error("tree: begin_fixed out of range");
--curdepth;
} while(tmp->next_sibling==0);
}
tmp=tmp->next_sibling;
}
tmp=tmp->first_child;
++curdepth;
}
ret.node=tmp;
return ret;
}
template
typename tree::fixed_depth_iterator tree::end_fixed(const iterator_base& pos, unsigned int dp) const
{
assert(1==0); // FIXME: not correct yet: use is_valid() as a temporary workaround
tree_node *tmp=pos.node;
unsigned int curdepth=1;
while(curdepthfirst_child==0) {
tmp=tmp->next_sibling;
if(tmp==0)
throw std::range_error("tree: end_fixed out of range");
}
tmp=tmp->first_child;
++curdepth;
}
return tmp;
}
template
typename tree::sibling_iterator tree::begin(const iterator_base& pos) const
{
assert(pos.node!=0);
if(pos.node->first_child==0) {
return end(pos);
}
return pos.node->first_child;
}
template
typename tree::sibling_iterator tree::end(const iterator_base& pos) const
{
sibling_iterator ret(0);
ret.parent_=pos.node;
return ret;
}
template
typename tree::leaf_iterator tree::begin_leaf() const
{
tree_node *tmp=head->next_sibling;
if(tmp!=feet) {
while(tmp->first_child)
tmp=tmp->first_child;
}
return leaf_iterator(tmp);
}
template
typename tree::leaf_iterator tree::end_leaf() const
{
return leaf_iterator(feet);
}
template
typename tree::leaf_iterator tree::begin_leaf(const iterator_base& top) const
{
tree_node *tmp=top.node;
while(tmp->first_child)
tmp=tmp->first_child;
return leaf_iterator(tmp, top.node);
}
template
typename tree::leaf_iterator tree::end_leaf(const iterator_base& top) const
{
return leaf_iterator(top.node, top.node);
}
template
template
iter tree::parent(iter position)
{
assert(position.node!=0);
return iter(position.node->parent);
}
template
template
iter tree::previous_sibling(iter position) const
{
assert(position.node!=0);
iter ret(position);
ret.node=position.node->prev_sibling;
return ret;
}
template
template
iter tree::next_sibling(iter position) const
{
assert(position.node!=0);
iter ret(position);
ret.node=position.node->next_sibling;
return ret;
}
template
template
iter tree::next_at_same_depth(iter position) const
{
// We make use of a temporary fixed_depth iterator to implement this.
typename tree::fixed_depth_iterator tmp(position.node);
++tmp;
return iter(tmp);
// assert(position.node!=0);
// iter ret(position);
//
// if(position.node->next_sibling) {
// ret.node=position.node->next_sibling;
// }
// else {
// int relative_depth=0;
// upper:
// do {
// ret.node=ret.node->parent;
// if(ret.node==0) return ret;
// --relative_depth;
// } while(ret.node->next_sibling==0);
// lower:
// ret.node=ret.node->next_sibling;
// while(ret.node->first_child==0) {
// if(ret.node->next_sibling==0)
// goto upper;
// ret.node=ret.node->next_sibling;
// if(ret.node==0) return ret;
// }
// while(relative_depth<0 && ret.node->first_child!=0) {
// ret.node=ret.node->first_child;
// ++relative_depth;
// }
// if(relative_depth<0) {
// if(ret.node->next_sibling==0) goto upper;
// else goto lower;
// }
// }
// return ret;
}
template
template
iter tree::append_child(iter position)
{
assert(position.node!=head);
assert(position.node!=feet);
assert(position.node);
tree_node *tmp=alloc_.allocate(1,0);
alloc_.construct(tmp, tree_node_());
// kp::constructor(&tmp->data);
tmp->first_child=0;
tmp->last_child=0;
tmp->parent=position.node;
if(position.node->last_child!=0) {
position.node->last_child->next_sibling=tmp;
}
else {
position.node->first_child=tmp;
}
tmp->prev_sibling=position.node->last_child;
position.node->last_child=tmp;
tmp->next_sibling=0;
return tmp;
}
template