cassiopee-c-1.0.7/0000755000174700017470000000000013213443214013151 5ustar debiandebiancassiopee-c-1.0.7/test/0000755000174700017470000000000013213443214014130 5ustar debiandebiancassiopee-c-1.0.7/test/CMakeLists.txt0000644000174700017470000000072713213443214016676 0ustar debiandebian# 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("${PROJECT_SOURCE_DIR}") include_directories("${CMAKE_SOURCE_DIR}/src") include( CTest ) add_executable(test_cassiopee test.cxx) target_link_libraries(test_cassiopee cassie glog cppunit) add_test(NAME "TestCassie" COMMAND ${PROJECT_BINARY_DIR}/test_cassiopee WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) cassiopee-c-1.0.7/test/test.h0000644000174700017470000000172513213443214015265 0ustar debiandebian#include class CassiopeeTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( CassiopeeTest ); CPPUNIT_TEST( testIndex ); CPPUNIT_TEST( testIndexWithReduction ); CPPUNIT_TEST( testSearchInReduction ); CPPUNIT_TEST( testAmbiguity ); CPPUNIT_TEST( testSearchWithError ); CPPUNIT_TEST( testSearchAfterN ); CPPUNIT_TEST( testSearchWithN ); CPPUNIT_TEST( testReducedSearchAfterN ); CPPUNIT_TEST( testReducedSearchWithN ); CPPUNIT_TEST( testProtein ); CPPUNIT_TEST( testLoadSave ); CPPUNIT_TEST( testMultiIndex ); CPPUNIT_TEST_SUITE_END(); public: void setUp(); void tearDown(); void testIndex(); void testIndexWithReduction(); void testSearchInReduction(); void testAmbiguity(); void testSearchWithError(); void testSearchAfterN(); void testSearchWithN(); void testReducedSearchAfterN(); void testReducedSearchWithN(); void testProtein(); void testLoadSave(); void testMultiIndex(); }; cassiopee-c-1.0.7/test/test.py0000644000174700017470000000177013213443214015466 0ustar debiandebian#!/usr/bin/python import os import sys import subprocess def searchPattern(pos, pattern): #print('Search, pos: '+str(i)+', '+pattern) subprocess.check_call(['../bin/cassiopee', '-p', pattern, '-s', 'test2.fasta.cass', '-o', 'test.out', '-r' ]) results = None with open('test.out', 'r') as res: results = res.readlines() if not results: return False match = False for result in results: elts = result.split('\t') if str(pos) == elts[0]: match = True break if not match: return False return True sequence = '' with open('test2.fasta.cass', 'r') as seq: sequence = seq.read() for i in range(0, len(sequence) - 1): for j in range(1, len(sequence) - i ): found = searchPattern(i, sequence[i:i+j]) if not found: print('Not found: pos: '+str(i)+', '+sequence[i:i+j]) sys.exit(1) cassiopee-c-1.0.7/test/test.cxx0000644000174700017470000002072213213443214015636 0ustar debiandebian#include #include #include #include #include #include #include "test.h" #include #include #include #include "Cassiopee.h" // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( CassiopeeTest ); void CassiopeeTest::setUp() { remove( "test/sequence.txt.cass.idx" ); } void CassiopeeTest::tearDown() { remove( "test/sequence.txt.cass.idx" ); } void CassiopeeTest::testIndex() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->search("ggc"); searcher->sort(); list matches = searcher->matches; if(matches.size()!=3) { cerr << matches.size() << "\n"; CPPUNIT_FAIL( "wrong number of match"); } std::list::iterator it = matches.begin(); if((*it)->pos != 16) { CPPUNIT_FAIL( "wrong position" ); } std::advance(it, 1); if((*it)->pos != 19) { CPPUNIT_FAIL( "wrong position" ); } std::advance(it, 1); if((*it)->pos != 42) { CPPUNIT_FAIL( "wrong position" ); } delete searcher; delete indexer; } void CassiopeeTest::testLoadSave() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->index(); long save_nodes = indexer->getTree()->size(); indexer->save(); CassieIndexer* indexer2 = new CassieIndexer(seq); indexer2->index(); if(! indexer2->index_loaded_from_file()) { CPPUNIT_FAIL( "index not loaded from saved index" ); } long load_nodes = indexer->getTree()->size(); delete indexer; delete indexer2; if(load_nodes != save_nodes) { CPPUNIT_FAIL( "loaded tree is different from saved tree" ); } } void CassiopeeTest::testMultiIndex() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->index(); long save_nodes = indexer->getTree()->size(); indexer->save(); indexer->index(); long save_nodes2 = indexer->getTree()->size(); if(save_nodes != save_nodes2) { CPPUNIT_FAIL( "index loaded twice" ); } delete indexer; } void CassiopeeTest::testIndexWithReduction() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->max_index_depth = 4; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->search("ggc"); searcher->sort(); list matches = searcher->matches; if(matches.size()!=3) { CPPUNIT_FAIL( "wrong number of match" ); } std::list::iterator it = matches.begin(); if((*it)->pos != 16) { CPPUNIT_FAIL( "wrong position" ); } std::advance(it, 1); if((*it)->pos != 19) { CPPUNIT_FAIL( "wrong position" ); } std::advance(it, 1); if((*it)->pos != 42) { CPPUNIT_FAIL( "wrong position" ); } delete searcher; delete indexer; } void CassiopeeTest::testSearchInReduction() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->search("gggcgcgggtgggtgggagagaa"); searcher->sort(); list matches = searcher->matches; if(matches.size()!=1) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } void CassiopeeTest::testProtein() { char sequence[] = "test/protein.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->mode = 2; searcher->search("GHIKLMNPQR"); searcher->sort(); list matches = searcher->matches; if(matches.size()!=1) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } void CassiopeeTest::testSearchWithError() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->max_index_depth = 4; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->max_subst = 1; searcher->search("ggc"); searcher->sort(); list matches = searcher->matches; std::list::iterator it = matches.begin(); // œœœœœœœœœœcout << "#### " << (*it)->pos << "\n"; if((*it)->pos != 15) { CPPUNIT_FAIL( "wrong position" ); } std::advance(it, 1); // cout << "#### " << (*it)->pos << "\n"; if((*it)->pos != 16) { CPPUNIT_FAIL( "wrong position" ); } delete searcher; delete indexer; } void CassiopeeTest::testAmbiguity() { char a = 'c'; char b = 'g'; if(Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong equal matching"); } b = 'b'; // c or g or t if(! Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on b"); } a = 'b'; b = 'g'; if(! Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on b"); } a = 'a'; b = 'n'; if(! Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on n"); } a = 'a'; b = 'r'; if(! Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on r"); } a = 'g'; b = 'r'; if(! Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on r"); } a = 't'; b = 'r'; if(Ambiguous::isequal(a,b)) { CPPUNIT_FAIL( "wrong ambiguous matching on r"); } } void CassiopeeTest::testSearchAfterN() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = false; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->search("tata"); searcher->sort(); list matches = searcher->matches; if(matches.size()==0) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } void CassiopeeTest::testSearchWithN() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = false; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->nmax = 1; searcher->search("gtata"); searcher->sort(); list matches = searcher->matches; if(matches.size()==0) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } void CassiopeeTest::testReducedSearchAfterN() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->search("tata"); searcher->sort(); list matches = searcher->matches; if(matches.size()==0) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } void CassiopeeTest::testReducedSearchWithN() { char sequence[] = "test/sequence.txt"; char* seq = sequence; CassieIndexer* indexer = new CassieIndexer(seq); indexer->do_reduction = true; indexer->index(); CassieSearch* searcher = new CassieSearch(indexer); searcher->nmax = 1; searcher->search("gtata"); searcher->sort(); list matches = searcher->matches; if(matches.size()==0) { CPPUNIT_FAIL( "wrong number of match" ); } delete searcher; delete indexer; } int main(int argc, char* argv[]) { CppUnit::TestResultCollector result; CppUnit::TestResult controller; controller.addListener( &result ); CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest( registry.makeTest() ); // Run the tests. runner.run(controller); // Print test in a compiler compatible format. CppUnit::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() ); outputter.write(); // Uncomment this for XML output std::ofstream file( "cppunit-report.xml" ); CppUnit::XmlOutputter xml( &result, file ); xml.write(); file.close(); // Return error code 1 if the one of test failed. return result.wasSuccessful() ? 0 : 1; } cassiopee-c-1.0.7/test/pattern.txt0000644000174700017470000000000613213443214016342 0ustar debiandebianagagg cassiopee-c-1.0.7/test/sequence.txt0000644000174700017470000000011413213443214016475 0ustar debiandebianaaaaaaaaaaaaagagggcggcggggggggggggggggggggggcgcgggtgggtgggagagaagaannnntata cassiopee-c-1.0.7/test/test2.fasta.cass0000644000174700017470000000004513213443214017140 0ustar debiandebiantattaggttggtgcaaaagtaattgcggtttttgcc cassiopee-c-1.0.7/test/protein.txt0000644000174700017470000000003013213443214016342 0ustar debiandebianacdefghiklmnpqrstvwybzx cassiopee-c-1.0.7/test/test.txt0000644000174700017470000000015013213443214015644 0ustar debiandebianbin/cassiopee -p ggtt -s test2.fasta.cass -o test.out -r -g dot -Tpng cassiopee.dot > cassiopee2.png cassiopee-c-1.0.7/CMakeLists.txt0000644000174700017470000000355613213443214015722 0ustar debiandebiancmake_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.7/src/0000755000174700017470000000000013213443214013740 5ustar debiandebiancassiopee-c-1.0.7/src/CMakeLists.txt0000644000174700017470000000210713213443214016500 0ustar debiandebian 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.7/src/Cassiopee.h0000644000174700017470000002346213213443214016033 0ustar debiandebian#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.7/src/CassiopeeConfig.h.in0000644000174700017470000000035013213443214017555 0ustar debiandebian// 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.7/src/cassiopee.cxx0000644000174700017470000007475213213443214016456 0ustar debiandebian// 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) { 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 ) { // LOG(ERROR) << "loop in reduction"; 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(ERROR) << "match " << suffix_char << " with " << tree_char << " at " << tree_reducted_pos << ", max=" << sib->next_length; 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; } } // LOG(ERROR) << "not equal, can substitute? " << isequal << ", " << nbSubst << ", " << this->max_subst; if(!isequal) { if(this->max_subst>0 && nbSubst < this->max_subst) { // Check for substitutions isequal = true; nbSubst++; } else { // LOG(ERROR) << "now break equal=" << isequal; break; } } } if(isequal) { // LOG(ERROR) << "IS EQUAL? " << isequal; if(counter == suffix.length() -1) { this->getMatchesFromNode(sib, nbSubst, nbIn, nbDel); return true; } else { //LOG(ERROR) << "full match but not complete, search childs"; // 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(ERROR) << "-- " << sib->next_pos << ", " << sib->next_length; //LOG(INFO) << "next " << sib->next_pos << ", " << sib->next_length; long tree_reducted_pos = -1; // Fix O.Sallou 08/04/16 search error with reduction // Fix O.Sallou 26/10/17 search error with reduction //counter++; 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); //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 << "-" << first->next_pos << "\"];\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; 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)); 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); 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); //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) { // Fix #1 folding issue - OSALLOU // Unfold reducted node while we have matches in reduction if(tree_reducted_pos > -1 && counter < suffix_len - 1){ tree_char = tolower(tree_char); TreeNode * tmp_node = new TreeNode(tree_char); tmp_node->next_length = sib->next_length - tree_reducted_pos - 1; tmp_node->next_pos = sib->next_pos + 1; if(sib->next_pos>=0){ std::list positions = sib->positions; for (std::list::iterator it = positions.begin(); it != positions.end(); it++) { tmp_node->positions.push_back(*it); } } sib->next_length = 0 ; sib->next_pos = -1; sib = this->tr.append_child(sib, *tmp_node); tree_reducted_pos--; } 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.7/src/cassie.cxx0000644000174700017470000001642513213443214015743 0ustar debiandebian// 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.7/src/Doxyfile.in0000644000174700017470000022362513213443214016065 0ustar debiandebian# 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 = NO # 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.7/src/knife.cxx0000644000174700017470000000264013213443214015562 0ustar debiandebian// 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.7/src/tree/0000755000174700017470000000000013213443214014677 5ustar debiandebiancassiopee-c-1.0.7/src/tree/tree_util.hh0000644000174700017470000000477113213443214017225 0ustar debiandebian/* A collection of miscellaneous utilities that operate on the templated tree.hh class. Copyright (C) 2001-2009 Kasper Peeters (At the moment this only contains a printing utility, thanks to Linda Buisman ) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef tree_util_hh_ #define tree_util_hh_ #include #include "tree.hh" namespace kptree { template void print_tree_bracketed(const tree& t, std::ostream& str=std::cout); template void print_subtree_bracketed(const tree& t, typename tree::iterator iRoot, std::ostream& str=std::cout); // Iterate over all roots (the head) and print each one on a new line // by calling printSingleRoot. template void print_tree_bracketed(const tree& t, std::ostream& str) { int headCount = t.number_of_siblings(t.begin()); int headNum = 0; for(typename tree::sibling_iterator iRoots = t.begin(); iRoots != t.end(); ++iRoots, ++headNum) { print_subtree_bracketed(t,iRoots,str); if (headNum != headCount) { str << std::endl; } } } // Print everything under this root in a flat, bracketed structure. template void print_subtree_bracketed(const tree& t, typename tree::iterator iRoot, std::ostream& str) { if(t.empty()) return; if (t.number_of_children(iRoot) == 0) { str << *iRoot; } else { // parent str << *iRoot; str << "("; // child1, ..., childn int siblingCount = t.number_of_siblings(t.begin(iRoot)); int siblingNum; typename tree::sibling_iterator iChildren; for (iChildren = t.begin(iRoot), siblingNum = 0; iChildren != t.end(iRoot); ++iChildren, ++siblingNum) { // recursively print child print_subtree_bracketed(t,iChildren,str); // comma after every child except the last one if (siblingNum != siblingCount ) { str << ", "; } } str << ")"; } } } #endif cassiopee-c-1.0.7/src/tree/tree.hh0000644000174700017470000024213313213443214016164 0ustar debiandebian // 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 template iter tree::prepend_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->first_child!=0) { position.node->first_child->prev_sibling=tmp; } else { position.node->last_child=tmp; } tmp->next_sibling=position.node->first_child; position.node->prev_child=tmp; tmp->prev_sibling=0; return tmp; } template template iter tree::append_child(iter position, const T& x) { // If your program fails here you probably used 'append_child' to add the top // node to an empty tree. From version 1.45 the top element should be added // using 'insert'. See the documentation for further information, and sorry about // the API change. assert(position.node!=head); assert(position.node!=feet); assert(position.node); tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, x); // kp::constructor(&tmp->data, x); 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 template iter tree::prepend_child(iter position, const T& x) { assert(position.node!=head); assert(position.node!=feet); assert(position.node); tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, x); // kp::constructor(&tmp->data, x); tmp->first_child=0; tmp->last_child=0; tmp->parent=position.node; if(position.node->first_child!=0) { position.node->first_child->prev_sibling=tmp; } else { position.node->last_child=tmp; } tmp->next_sibling=position.node->first_child; position.node->first_child=tmp; tmp->prev_sibling=0; return tmp; } template template iter tree::append_child(iter position, iter other) { assert(position.node!=head); assert(position.node!=feet); assert(position.node); sibling_iterator aargh=append_child(position, value_type()); return replace(aargh, other); } template template iter tree::prepend_child(iter position, iter other) { assert(position.node!=head); assert(position.node!=feet); assert(position.node); sibling_iterator aargh=prepend_child(position, value_type()); return replace(aargh, other); } template template iter tree::append_children(iter position, sibling_iterator from, sibling_iterator to) { assert(position.node!=head); assert(position.node!=feet); assert(position.node); iter ret=from; while(from!=to) { insert_subtree(position.end(), from); ++from; } return ret; } template template iter tree::prepend_children(iter position, sibling_iterator from, sibling_iterator to) { assert(position.node!=head); assert(position.node!=feet); assert(position.node); iter ret=from; while(from!=to) { insert_subtree(position.begin(), from); ++from; } return ret; } template typename tree::pre_order_iterator tree::set_head(const T& x) { assert(head->next_sibling==feet); return insert(iterator(feet), x); } template template iter tree::insert(iter position, const T& x) { if(position.node==0) { position.node=feet; // Backward compatibility: when calling insert on a null node, // insert before the feet. } tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, x); // kp::constructor(&tmp->data, x); tmp->first_child=0; tmp->last_child=0; tmp->parent=position.node->parent; tmp->next_sibling=position.node; tmp->prev_sibling=position.node->prev_sibling; position.node->prev_sibling=tmp; if(tmp->prev_sibling==0) { if(tmp->parent) // when inserting nodes at the head, there is no parent tmp->parent->first_child=tmp; } else tmp->prev_sibling->next_sibling=tmp; return tmp; } template typename tree::sibling_iterator tree::insert(sibling_iterator position, const T& x) { tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, x); // kp::constructor(&tmp->data, x); tmp->first_child=0; tmp->last_child=0; tmp->next_sibling=position.node; if(position.node==0) { // iterator points to end of a subtree tmp->parent=position.parent_; tmp->prev_sibling=position.range_last(); tmp->parent->last_child=tmp; } else { tmp->parent=position.node->parent; tmp->prev_sibling=position.node->prev_sibling; position.node->prev_sibling=tmp; } if(tmp->prev_sibling==0) { if(tmp->parent) // when inserting nodes at the head, there is no parent tmp->parent->first_child=tmp; } else tmp->prev_sibling->next_sibling=tmp; return tmp; } template template iter tree::insert_after(iter position, const T& x) { tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, x); // kp::constructor(&tmp->data, x); tmp->first_child=0; tmp->last_child=0; tmp->parent=position.node->parent; tmp->prev_sibling=position.node; tmp->next_sibling=position.node->next_sibling; position.node->next_sibling=tmp; if(tmp->next_sibling==0) { if(tmp->parent) // when inserting nodes at the head, there is no parent tmp->parent->last_child=tmp; } else { tmp->next_sibling->prev_sibling=tmp; } return tmp; } template template iter tree::insert_subtree(iter position, const iterator_base& subtree) { // insert dummy iter it=insert(position, value_type()); // replace dummy with subtree return replace(it, subtree); } template template iter tree::insert_subtree_after(iter position, const iterator_base& subtree) { // insert dummy iter it=insert_after(position, value_type()); // replace dummy with subtree return replace(it, subtree); } // template // template // iter tree::insert_subtree(sibling_iterator position, iter subtree) // { // // insert dummy // iter it(insert(position, value_type())); // // replace dummy with subtree // return replace(it, subtree); // } template template iter tree::replace(iter position, const T& x) { // kp::destructor(&position.node->data); // kp::constructor(&position.node->data, x); position.node->data=x; // alloc_.destroy(position.node); // alloc_.construct(position.node, x); return position; } template template iter tree::replace(iter position, const iterator_base& from) { assert(position.node!=head); tree_node *current_from=from.node; tree_node *start_from=from.node; tree_node *current_to =position.node; // replace the node at position with head of the replacement tree at from // std::cout << "warning!" << position.node << std::endl; erase_children(position); // std::cout << "no warning!" << std::endl; tree_node* tmp = alloc_.allocate(1,0); alloc_.construct(tmp, (*from)); // kp::constructor(&tmp->data, (*from)); tmp->first_child=0; tmp->last_child=0; if(current_to->prev_sibling==0) { if(current_to->parent!=0) current_to->parent->first_child=tmp; } else { current_to->prev_sibling->next_sibling=tmp; } tmp->prev_sibling=current_to->prev_sibling; if(current_to->next_sibling==0) { if(current_to->parent!=0) current_to->parent->last_child=tmp; } else { current_to->next_sibling->prev_sibling=tmp; } tmp->next_sibling=current_to->next_sibling; tmp->parent=current_to->parent; // kp::destructor(¤t_to->data); alloc_.destroy(current_to); alloc_.deallocate(current_to,1); current_to=tmp; // only at this stage can we fix 'last' tree_node *last=from.node->next_sibling; pre_order_iterator toit=tmp; // copy all children do { assert(current_from!=0); if(current_from->first_child != 0) { current_from=current_from->first_child; toit=append_child(toit, current_from->data); } else { while(current_from->next_sibling==0 && current_from!=start_from) { current_from=current_from->parent; toit=parent(toit); assert(current_from!=0); } current_from=current_from->next_sibling; if(current_from!=last) { toit=append_child(parent(toit), current_from->data); } } } while(current_from!=last); return current_to; } template typename tree::sibling_iterator tree::replace( sibling_iterator orig_begin, sibling_iterator orig_end, sibling_iterator new_begin, sibling_iterator new_end) { tree_node *orig_first=orig_begin.node; tree_node *new_first=new_begin.node; tree_node *orig_last=orig_first; while((++orig_begin)!=orig_end) orig_last=orig_last->next_sibling; tree_node *new_last=new_first; while((++new_begin)!=new_end) new_last=new_last->next_sibling; // insert all siblings in new_first..new_last before orig_first bool first=true; pre_order_iterator ret; while(1==1) { pre_order_iterator tt=insert_subtree(pre_order_iterator(orig_first), pre_order_iterator(new_first)); if(first) { ret=tt; first=false; } if(new_first==new_last) break; new_first=new_first->next_sibling; } // erase old range of siblings bool last=false; tree_node *next=orig_first; while(1==1) { if(next==orig_last) last=true; next=next->next_sibling; erase((pre_order_iterator)orig_first); if(last) break; orig_first=next; } return ret; } template template iter tree::flatten(iter position) { if(position.node->first_child==0) return position; tree_node *tmp=position.node->first_child; while(tmp) { tmp->parent=position.node->parent; tmp=tmp->next_sibling; } if(position.node->next_sibling) { position.node->last_child->next_sibling=position.node->next_sibling; position.node->next_sibling->prev_sibling=position.node->last_child; } else { position.node->parent->last_child=position.node->last_child; } position.node->next_sibling=position.node->first_child; position.node->next_sibling->prev_sibling=position.node; position.node->first_child=0; position.node->last_child=0; return position; } template template iter tree::reparent(iter position, sibling_iterator begin, sibling_iterator end) { tree_node *first=begin.node; tree_node *last=first; assert(first!=position.node); if(begin==end) return begin; // determine last node while((++begin)!=end) { last=last->next_sibling; } // move subtree if(first->prev_sibling==0) { first->parent->first_child=last->next_sibling; } else { first->prev_sibling->next_sibling=last->next_sibling; } if(last->next_sibling==0) { last->parent->last_child=first->prev_sibling; } else { last->next_sibling->prev_sibling=first->prev_sibling; } if(position.node->first_child==0) { position.node->first_child=first; position.node->last_child=last; first->prev_sibling=0; } else { position.node->last_child->next_sibling=first; first->prev_sibling=position.node->last_child; position.node->last_child=last; } last->next_sibling=0; tree_node *pos=first; for(;;) { pos->parent=position.node; if(pos==last) break; pos=pos->next_sibling; } return first; } template template iter tree::reparent(iter position, iter from) { if(from.node->first_child==0) return position; return reparent(position, from.node->first_child, end(from)); } template template iter tree::wrap(iter position, const T& x) { assert(position.node!=0); sibling_iterator fr=position, to=position; ++to; iter ret = insert(position, x); reparent(ret, fr, to); return ret; } template template iter tree::move_after(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; if(dst->next_sibling) if(dst->next_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst->next_sibling!=0) dst->next_sibling->prev_sibling=src; else dst->parent->last_child=src; src->next_sibling=dst->next_sibling; dst->next_sibling=src; src->prev_sibling=dst; src->parent=dst->parent; return src; } template template iter tree::move_before(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; if(dst->prev_sibling) if(dst->prev_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst->prev_sibling!=0) dst->prev_sibling->next_sibling=src; else dst->parent->first_child=src; src->prev_sibling=dst->prev_sibling; dst->prev_sibling=src; src->next_sibling=dst; src->parent=dst->parent; return src; } // specialisation for sibling_iterators template typename tree::sibling_iterator tree::move_before(sibling_iterator target, sibling_iterator source) { tree_node *dst=target.node; tree_node *src=source.node; tree_node *dst_prev_sibling; if(dst==0) { // must then be an end iterator dst_prev_sibling=target.parent_->last_child; assert(dst_prev_sibling); } else dst_prev_sibling=dst->prev_sibling; assert(src); if(dst==src) return source; if(dst_prev_sibling) if(dst_prev_sibling==src) // already in the right spot return source; // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(dst_prev_sibling!=0) dst_prev_sibling->next_sibling=src; else target.parent_->first_child=src; src->prev_sibling=dst_prev_sibling; if(dst) { dst->prev_sibling=src; src->parent=dst->parent; } src->next_sibling=dst; return src; } template template iter tree::move_ontop(iter target, iter source) { tree_node *dst=target.node; tree_node *src=source.node; assert(dst); assert(src); if(dst==src) return source; // if(dst==src->prev_sibling) { // // } // remember connection points tree_node *b_prev_sibling=dst->prev_sibling; tree_node *b_next_sibling=dst->next_sibling; tree_node *b_parent=dst->parent; // remove target erase(target); // take src out of the tree if(src->prev_sibling!=0) src->prev_sibling->next_sibling=src->next_sibling; else src->parent->first_child=src->next_sibling; if(src->next_sibling!=0) src->next_sibling->prev_sibling=src->prev_sibling; else src->parent->last_child=src->prev_sibling; // connect it to the new point if(b_prev_sibling!=0) b_prev_sibling->next_sibling=src; else b_parent->first_child=src; if(b_next_sibling!=0) b_next_sibling->prev_sibling=src; else b_parent->last_child=src; src->prev_sibling=b_prev_sibling; src->next_sibling=b_next_sibling; src->parent=b_parent; return src; } template void tree::merge(sibling_iterator to1, sibling_iterator to2, sibling_iterator from1, sibling_iterator from2, bool duplicate_leaves) { sibling_iterator fnd; while(from1!=from2) { if((fnd=std::find(to1, to2, (*from1))) != to2) { // element found if(from1.begin()==from1.end()) { // full depth reached if(duplicate_leaves) append_child(parent(to1), (*from1)); } else { // descend further merge(fnd.begin(), fnd.end(), from1.begin(), from1.end(), duplicate_leaves); } } else { // element missing insert_subtree(to2, from1); } ++from1; } } template void tree::sort(sibling_iterator from, sibling_iterator to, bool deep) { std::less comp; sort(from, to, comp, deep); } template template void tree::sort(sibling_iterator from, sibling_iterator to, StrictWeakOrdering comp, bool deep) { if(from==to) return; // make list of sorted nodes // CHECK: if multiset stores equivalent nodes in the order in which they // are inserted, then this routine should be called 'stable_sort'. std::multiset > nodes(comp); sibling_iterator it=from, it2=to; while(it != to) { nodes.insert(it.node); ++it; } // reassemble --it2; // prev and next are the nodes before and after the sorted range tree_node *prev=from.node->prev_sibling; tree_node *next=it2.node->next_sibling; typename std::multiset >::iterator nit=nodes.begin(), eit=nodes.end(); if(prev==0) { if((*nit)->parent!=0) // to catch "sorting the head" situations, when there is no parent (*nit)->parent->first_child=(*nit); } else prev->next_sibling=(*nit); --eit; while(nit!=eit) { (*nit)->prev_sibling=prev; if(prev) prev->next_sibling=(*nit); prev=(*nit); ++nit; } // prev now points to the last-but-one node in the sorted range if(prev) prev->next_sibling=(*eit); // eit points to the last node in the sorted range. (*eit)->next_sibling=next; (*eit)->prev_sibling=prev; // missed in the loop above if(next==0) { if((*eit)->parent!=0) // to catch "sorting the head" situations, when there is no parent (*eit)->parent->last_child=(*eit); } else next->prev_sibling=(*eit); if(deep) { // sort the children of each node too sibling_iterator bcs(*nodes.begin()); sibling_iterator ecs(*eit); ++ecs; while(bcs!=ecs) { sort(begin(bcs), end(bcs), comp, deep); ++bcs; } } } template template bool tree::equal(const iter& one_, const iter& two, const iter& three_) const { std::equal_to comp; return equal(one_, two, three_, comp); } template template bool tree::equal_subtree(const iter& one_, const iter& two_) const { std::equal_to comp; return equal_subtree(one_, two_, comp); } template template bool tree::equal(const iter& one_, const iter& two, const iter& three_, BinaryPredicate fun) const { pre_order_iterator one(one_), three(three_); // if(one==two && is_valid(three) && three.number_of_children()!=0) // return false; while(one!=two && is_valid(three)) { if(!fun(*one,*three)) return false; if(one.number_of_children()!=three.number_of_children()) return false; ++one; ++three; } return true; } template template bool tree::equal_subtree(const iter& one_, const iter& two_, BinaryPredicate fun) const { pre_order_iterator one(one_), two(two_); if(!fun(*one,*two)) return false; if(number_of_children(one)!=number_of_children(two)) return false; return equal(begin(one),end(one),begin(two),fun); } template tree tree::subtree(sibling_iterator from, sibling_iterator to) const { tree tmp; tmp.set_head(value_type()); tmp.replace(tmp.begin(), tmp.end(), from, to); return tmp; } template void tree::subtree(tree& tmp, sibling_iterator from, sibling_iterator to) const { tmp.set_head(value_type()); tmp.replace(tmp.begin(), tmp.end(), from, to); } template size_t tree::size() const { size_t i=0; pre_order_iterator it=begin(), eit=end(); while(it!=eit) { ++i; ++it; } return i; } template size_t tree::size(const iterator_base& top) const { size_t i=0; pre_order_iterator it=top, eit=top; eit.skip_children(); ++eit; while(it!=eit) { ++i; ++it; } return i; } template bool tree::empty() const { pre_order_iterator it=begin(), eit=end(); return (it==eit); } template int tree::depth(const iterator_base& it) { tree_node* pos=it.node; assert(pos!=0); int ret=0; while(pos->parent!=0) { pos=pos->parent; ++ret; } return ret; } template int tree::depth(const iterator_base& it, const iterator_base& root) { tree_node* pos=it.node; assert(pos!=0); int ret=0; while(pos->parent!=0 && pos!=root.node) { pos=pos->parent; ++ret; } return ret; } template int tree::max_depth() const { int maxd=-1; for(tree_node *it = head->next_sibling; it!=feet; it=it->next_sibling) maxd=std::max(maxd, max_depth(it)); return maxd; } template int tree::max_depth(const iterator_base& pos) const { tree_node *tmp=pos.node; if(tmp==0 || tmp==head || tmp==feet) return -1; int curdepth=0, maxdepth=0; while(true) { // try to walk the bottom of the tree while(tmp->first_child==0) { if(tmp==pos.node) return maxdepth; if(tmp->next_sibling==0) { // try to walk up and then right again do { tmp=tmp->parent; if(tmp==0) return maxdepth; --curdepth; } while(tmp->next_sibling==0); } if(tmp==pos.node) return maxdepth; tmp=tmp->next_sibling; } tmp=tmp->first_child; ++curdepth; maxdepth=std::max(curdepth, maxdepth); } } template unsigned int tree::number_of_children(const iterator_base& it) { tree_node *pos=it.node->first_child; if(pos==0) return 0; unsigned int ret=1; // while(pos!=it.node->last_child) { // ++ret; // pos=pos->next_sibling; // } while((pos=pos->next_sibling)) ++ret; return ret; } template unsigned int tree::number_of_siblings(const iterator_base& it) const { tree_node *pos=it.node; unsigned int ret=0; // count forward while(pos->next_sibling && pos->next_sibling!=head && pos->next_sibling!=feet) { ++ret; pos=pos->next_sibling; } // count backward pos=it.node; while(pos->prev_sibling && pos->prev_sibling!=head && pos->prev_sibling!=feet) { ++ret; pos=pos->prev_sibling; } return ret; } template void tree::swap(sibling_iterator it) { tree_node *nxt=it.node->next_sibling; if(nxt) { if(it.node->prev_sibling) it.node->prev_sibling->next_sibling=nxt; else it.node->parent->first_child=nxt; nxt->prev_sibling=it.node->prev_sibling; tree_node *nxtnxt=nxt->next_sibling; if(nxtnxt) nxtnxt->prev_sibling=it.node; else it.node->parent->last_child=it.node; nxt->next_sibling=it.node; it.node->prev_sibling=nxt; it.node->next_sibling=nxtnxt; } } template void tree::swap(iterator one, iterator two) { // if one and two are adjacent siblings, use the sibling swap if(one.node->next_sibling==two.node) swap(one); else if(two.node->next_sibling==one.node) swap(two); else { tree_node *nxt1=one.node->next_sibling; tree_node *nxt2=two.node->next_sibling; tree_node *pre1=one.node->prev_sibling; tree_node *pre2=two.node->prev_sibling; tree_node *par1=one.node->parent; tree_node *par2=two.node->parent; // reconnect one.node->parent=par2; one.node->next_sibling=nxt2; if(nxt2) nxt2->prev_sibling=one.node; else par2->last_child=one.node; one.node->prev_sibling=pre2; if(pre2) pre2->next_sibling=one.node; else par2->first_child=one.node; two.node->parent=par1; two.node->next_sibling=nxt1; if(nxt1) nxt1->prev_sibling=two.node; else par1->last_child=two.node; two.node->prev_sibling=pre1; if(pre1) pre1->next_sibling=two.node; else par1->first_child=two.node; } } // template // tree::iterator tree::find_subtree( // sibling_iterator subfrom, sibling_iterator subto, iterator from, iterator to, // BinaryPredicate fun) const // { // assert(1==0); // this routine is not finished yet. // while(from!=to) { // if(fun(*subfrom, *from)) { // // } // } // return to; // } template bool tree::is_in_subtree(const iterator_base& it, const iterator_base& begin, const iterator_base& end) const { // FIXME: this should be optimised. pre_order_iterator tmp=begin; while(tmp!=end) { if(tmp==it) return true; ++tmp; } return false; } template bool tree::is_valid(const iterator_base& it) const { if(it.node==0 || it.node==feet || it.node==head) return false; else return true; } template typename tree::iterator tree::lowest_common_ancestor( const iterator_base& one, const iterator_base& two) const { std::set parents; // Walk up from 'one' storing all parents. iterator walk=one; do { walk=parent(walk); parents.insert(walk); } while( is_valid(parent(walk)) ); // Walk up from 'two' until we encounter a node in parents. walk=two; do { walk=parent(walk); if(parents.find(walk) != parents.end()) break; } while( is_valid(parent(walk)) ); return walk; } template unsigned int tree::index(sibling_iterator it) const { unsigned int ind=0; if(it.node->parent==0) { while(it.node->prev_sibling!=head) { it.node=it.node->prev_sibling; ++ind; } } else { while(it.node->prev_sibling!=0) { it.node=it.node->prev_sibling; ++ind; } } return ind; } template typename tree::sibling_iterator tree::sibling(const iterator_base& it, unsigned int num) { tree_node *tmp; if(it.node->parent==0) { tmp=head->next_sibling; while(num) { tmp = tmp->next_sibling; --num; } } else { tmp=it.node->parent->first_child; while(num) { assert(tmp!=0); tmp = tmp->next_sibling; --num; } } return tmp; } template void tree::debug_verify_consistency() const { iterator it=begin(); while(it!=end()) { if(it.node->parent!=0) { if(it.node->prev_sibling==0) assert(it.node->parent->first_child==it.node); else assert(it.node->prev_sibling->next_sibling==it.node); if(it.node->next_sibling==0) assert(it.node->parent->last_child==it.node); else assert(it.node->next_sibling->prev_sibling==it.node); } ++it; } } template typename tree::sibling_iterator tree::child(const iterator_base& it, unsigned int num) { tree_node *tmp=it.node->first_child; while(num--) { assert(tmp!=0); tmp=tmp->next_sibling; } return tmp; } // Iterator base template tree::iterator_base::iterator_base() : node(0), skip_current_children_(false) { } template tree::iterator_base::iterator_base(tree_node *tn) : node(tn), skip_current_children_(false) { } template T& tree::iterator_base::operator*() const { return node->data; } template T* tree::iterator_base::operator->() const { return &(node->data); } template bool tree::post_order_iterator::operator!=(const post_order_iterator& other) const { if(other.node!=this->node) return true; else return false; } template bool tree::post_order_iterator::operator==(const post_order_iterator& other) const { if(other.node==this->node) return true; else return false; } template bool tree::pre_order_iterator::operator!=(const pre_order_iterator& other) const { if(other.node!=this->node) return true; else return false; } template bool tree::pre_order_iterator::operator==(const pre_order_iterator& other) const { if(other.node==this->node) return true; else return false; } template bool tree::sibling_iterator::operator!=(const sibling_iterator& other) const { if(other.node!=this->node) return true; else return false; } template bool tree::sibling_iterator::operator==(const sibling_iterator& other) const { if(other.node==this->node) return true; else return false; } template bool tree::leaf_iterator::operator!=(const leaf_iterator& other) const { if(other.node!=this->node) return true; else return false; } template bool tree::leaf_iterator::operator==(const leaf_iterator& other) const { if(other.node==this->node && other.top_node==this->top_node) return true; else return false; } template typename tree::sibling_iterator tree::iterator_base::begin() const { if(node->first_child==0) return end(); sibling_iterator ret(node->first_child); ret.parent_=this->node; return ret; } template typename tree::sibling_iterator tree::iterator_base::end() const { sibling_iterator ret(0); ret.parent_=node; return ret; } template void tree::iterator_base::skip_children() { skip_current_children_=true; } template void tree::iterator_base::skip_children(bool skip) { skip_current_children_=skip; } template unsigned int tree::iterator_base::number_of_children() const { tree_node *pos=node->first_child; if(pos==0) return 0; unsigned int ret=1; while(pos!=node->last_child) { ++ret; pos=pos->next_sibling; } return ret; } // Pre-order iterator template tree::pre_order_iterator::pre_order_iterator() : iterator_base(0) { } template tree::pre_order_iterator::pre_order_iterator(tree_node *tn) : iterator_base(tn) { } template tree::pre_order_iterator::pre_order_iterator(const iterator_base &other) : iterator_base(other.node) { } template tree::pre_order_iterator::pre_order_iterator(const sibling_iterator& other) : iterator_base(other.node) { if(this->node==0) { if(other.range_last()!=0) this->node=other.range_last(); else this->node=other.parent_; this->skip_children(); ++(*this); } } template typename tree::pre_order_iterator& tree::pre_order_iterator::operator++() { assert(this->node!=0); if(!this->skip_current_children_ && this->node->first_child != 0) { this->node=this->node->first_child; } else { this->skip_current_children_=false; while(this->node->next_sibling==0) { this->node=this->node->parent; if(this->node==0) return *this; } this->node=this->node->next_sibling; } return *this; } template typename tree::pre_order_iterator& tree::pre_order_iterator::operator--() { assert(this->node!=0); if(this->node->prev_sibling) { this->node=this->node->prev_sibling; while(this->node->last_child) this->node=this->node->last_child; } else { this->node=this->node->parent; if(this->node==0) return *this; } return *this; } template typename tree::pre_order_iterator tree::pre_order_iterator::operator++(int) { pre_order_iterator copy = *this; ++(*this); return copy; } template typename tree::pre_order_iterator tree::pre_order_iterator::operator--(int) { pre_order_iterator copy = *this; --(*this); return copy; } template typename tree::pre_order_iterator& tree::pre_order_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --num; } return (*this); } template typename tree::pre_order_iterator& tree::pre_order_iterator::operator-=(unsigned int num) { while(num>0) { --(*this); --num; } return (*this); } // Post-order iterator template tree::post_order_iterator::post_order_iterator() : iterator_base(0) { } template tree::post_order_iterator::post_order_iterator(tree_node *tn) : iterator_base(tn) { } template tree::post_order_iterator::post_order_iterator(const iterator_base &other) : iterator_base(other.node) { } template tree::post_order_iterator::post_order_iterator(const sibling_iterator& other) : iterator_base(other.node) { if(this->node==0) { if(other.range_last()!=0) this->node=other.range_last(); else this->node=other.parent_; this->skip_children(); ++(*this); } } template typename tree::post_order_iterator& tree::post_order_iterator::operator++() { assert(this->node!=0); if(this->node->next_sibling==0) { this->node=this->node->parent; this->skip_current_children_=false; } else { this->node=this->node->next_sibling; if(this->skip_current_children_) { this->skip_current_children_=false; } else { while(this->node->first_child) this->node=this->node->first_child; } } return *this; } template typename tree::post_order_iterator& tree::post_order_iterator::operator--() { assert(this->node!=0); if(this->skip_current_children_ || this->node->last_child==0) { this->skip_current_children_=false; while(this->node->prev_sibling==0) this->node=this->node->parent; this->node=this->node->prev_sibling; } else { this->node=this->node->last_child; } return *this; } template typename tree::post_order_iterator tree::post_order_iterator::operator++(int) { post_order_iterator copy = *this; ++(*this); return copy; } template typename tree::post_order_iterator tree::post_order_iterator::operator--(int) { post_order_iterator copy = *this; --(*this); return copy; } template typename tree::post_order_iterator& tree::post_order_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --num; } return (*this); } template typename tree::post_order_iterator& tree::post_order_iterator::operator-=(unsigned int num) { while(num>0) { --(*this); --num; } return (*this); } template void tree::post_order_iterator::descend_all() { assert(this->node!=0); while(this->node->first_child) this->node=this->node->first_child; } // Breadth-first iterator template tree::breadth_first_queued_iterator::breadth_first_queued_iterator() : iterator_base() { } template tree::breadth_first_queued_iterator::breadth_first_queued_iterator(tree_node *tn) : iterator_base(tn) { traversal_queue.push(tn); } template tree::breadth_first_queued_iterator::breadth_first_queued_iterator(const iterator_base& other) : iterator_base(other.node) { traversal_queue.push(other.node); } template bool tree::breadth_first_queued_iterator::operator!=(const breadth_first_queued_iterator& other) const { if(other.node!=this->node) return true; else return false; } template bool tree::breadth_first_queued_iterator::operator==(const breadth_first_queued_iterator& other) const { if(other.node==this->node) return true; else return false; } template typename tree::breadth_first_queued_iterator& tree::breadth_first_queued_iterator::operator++() { assert(this->node!=0); // Add child nodes and pop current node sibling_iterator sib=this->begin(); while(sib!=this->end()) { traversal_queue.push(sib.node); ++sib; } traversal_queue.pop(); if(traversal_queue.size()>0) this->node=traversal_queue.front(); else this->node=0; return (*this); } template typename tree::breadth_first_queued_iterator tree::breadth_first_queued_iterator::operator++(int) { breadth_first_queued_iterator copy = *this; ++(*this); return copy; } template typename tree::breadth_first_queued_iterator& tree::breadth_first_queued_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --num; } return (*this); } // Fixed depth iterator template tree::fixed_depth_iterator::fixed_depth_iterator() : iterator_base() { } template tree::fixed_depth_iterator::fixed_depth_iterator(tree_node *tn) : iterator_base(tn), top_node(0) { } template tree::fixed_depth_iterator::fixed_depth_iterator(const iterator_base& other) : iterator_base(other.node), top_node(0) { } template tree::fixed_depth_iterator::fixed_depth_iterator(const sibling_iterator& other) : iterator_base(other.node), top_node(0) { } template tree::fixed_depth_iterator::fixed_depth_iterator(const fixed_depth_iterator& other) : iterator_base(other.node), top_node(other.top_node) { } template bool tree::fixed_depth_iterator::operator==(const fixed_depth_iterator& other) const { if(other.node==this->node && other.top_node==top_node) return true; else return false; } template bool tree::fixed_depth_iterator::operator!=(const fixed_depth_iterator& other) const { if(other.node!=this->node || other.top_node!=top_node) return true; else return false; } template typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator++() { assert(this->node!=0); if(this->node->next_sibling) { this->node=this->node->next_sibling; } else { int relative_depth=0; upper: do { if(this->node==this->top_node) { this->node=0; // FIXME: return a proper fixed_depth end iterator once implemented return *this; } this->node=this->node->parent; if(this->node==0) return *this; --relative_depth; } while(this->node->next_sibling==0); lower: this->node=this->node->next_sibling; while(this->node->first_child==0) { if(this->node->next_sibling==0) goto upper; this->node=this->node->next_sibling; if(this->node==0) return *this; } while(relative_depth<0 && this->node->first_child!=0) { this->node=this->node->first_child; ++relative_depth; } if(relative_depth<0) { if(this->node->next_sibling==0) goto upper; else goto lower; } } return *this; } template typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator--() { assert(this->node!=0); if(this->node->prev_sibling) { this->node=this->node->prev_sibling; } else { int relative_depth=0; upper: do { if(this->node==this->top_node) { this->node=0; return *this; } this->node=this->node->parent; if(this->node==0) return *this; --relative_depth; } while(this->node->prev_sibling==0); lower: this->node=this->node->prev_sibling; while(this->node->last_child==0) { if(this->node->prev_sibling==0) goto upper; this->node=this->node->prev_sibling; if(this->node==0) return *this; } while(relative_depth<0 && this->node->last_child!=0) { this->node=this->node->last_child; ++relative_depth; } if(relative_depth<0) { if(this->node->prev_sibling==0) goto upper; else goto lower; } } return *this; // // // assert(this->node!=0); // if(this->node->prev_sibling!=0) { // this->node=this->node->prev_sibling; // assert(this->node!=0); // if(this->node->parent==0 && this->node->prev_sibling==0) // head element // this->node=0; // } // else { // tree_node *par=this->node->parent; // do { // par=par->prev_sibling; // if(par==0) { // FIXME: need to keep track of this! // this->node=0; // return *this; // } // } while(par->last_child==0); // this->node=par->last_child; // } // return *this; } template typename tree::fixed_depth_iterator tree::fixed_depth_iterator::operator++(int) { fixed_depth_iterator copy = *this; ++(*this); return copy; } template typename tree::fixed_depth_iterator tree::fixed_depth_iterator::operator--(int) { fixed_depth_iterator copy = *this; --(*this); return copy; } template typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator-=(unsigned int num) { while(num>0) { --(*this); --(num); } return (*this); } template typename tree::fixed_depth_iterator& tree::fixed_depth_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --(num); } return *this; } // Sibling iterator template tree::sibling_iterator::sibling_iterator() : iterator_base() { set_parent_(); } template tree::sibling_iterator::sibling_iterator(tree_node *tn) : iterator_base(tn) { set_parent_(); } template tree::sibling_iterator::sibling_iterator(const iterator_base& other) : iterator_base(other.node) { set_parent_(); } template tree::sibling_iterator::sibling_iterator(const sibling_iterator& other) : iterator_base(other), parent_(other.parent_) { } template void tree::sibling_iterator::set_parent_() { parent_=0; if(this->node==0) return; if(this->node->parent!=0) parent_=this->node->parent; } template typename tree::sibling_iterator& tree::sibling_iterator::operator++() { if(this->node) this->node=this->node->next_sibling; return *this; } template typename tree::sibling_iterator& tree::sibling_iterator::operator--() { if(this->node) this->node=this->node->prev_sibling; else { assert(parent_); this->node=parent_->last_child; } return *this; } template typename tree::sibling_iterator tree::sibling_iterator::operator++(int) { sibling_iterator copy = *this; ++(*this); return copy; } template typename tree::sibling_iterator tree::sibling_iterator::operator--(int) { sibling_iterator copy = *this; --(*this); return copy; } template typename tree::sibling_iterator& tree::sibling_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --num; } return (*this); } template typename tree::sibling_iterator& tree::sibling_iterator::operator-=(unsigned int num) { while(num>0) { --(*this); --num; } return (*this); } template typename tree::tree_node *tree::sibling_iterator::range_first() const { tree_node *tmp=parent_->first_child; return tmp; } template typename tree::tree_node *tree::sibling_iterator::range_last() const { return parent_->last_child; } // Leaf iterator template tree::leaf_iterator::leaf_iterator() : iterator_base(0), top_node(0) { } template tree::leaf_iterator::leaf_iterator(tree_node *tn, tree_node *top) : iterator_base(tn), top_node(top) { } template tree::leaf_iterator::leaf_iterator(const iterator_base &other) : iterator_base(other.node), top_node(0) { } template tree::leaf_iterator::leaf_iterator(const sibling_iterator& other) : iterator_base(other.node), top_node(0) { if(this->node==0) { if(other.range_last()!=0) this->node=other.range_last(); else this->node=other.parent_; ++(*this); } } template typename tree::leaf_iterator& tree::leaf_iterator::operator++() { assert(this->node!=0); if(this->node->first_child!=0) { // current node is no longer leaf (children got added) while(this->node->first_child) this->node=this->node->first_child; } else { while(this->node->next_sibling==0) { if (this->node->parent==0) return *this; this->node=this->node->parent; if (top_node != 0 && this->node==top_node) return *this; } this->node=this->node->next_sibling; while(this->node->first_child) this->node=this->node->first_child; } return *this; } template typename tree::leaf_iterator& tree::leaf_iterator::operator--() { assert(this->node!=0); while (this->node->prev_sibling==0) { if (this->node->parent==0) return *this; this->node=this->node->parent; if (top_node !=0 && this->node==top_node) return *this; } this->node=this->node->prev_sibling; while(this->node->last_child) this->node=this->node->last_child; return *this; } template typename tree::leaf_iterator tree::leaf_iterator::operator++(int) { leaf_iterator copy = *this; ++(*this); return copy; } template typename tree::leaf_iterator tree::leaf_iterator::operator--(int) { leaf_iterator copy = *this; --(*this); return copy; } template typename tree::leaf_iterator& tree::leaf_iterator::operator+=(unsigned int num) { while(num>0) { ++(*this); --num; } return (*this); } template typename tree::leaf_iterator& tree::leaf_iterator::operator-=(unsigned int num) { while(num>0) { --(*this); --num; } return (*this); } #endif // Local variables: // default-tab-width: 3 // End: cassiopee-c-1.0.7/.cproject0000644000174700017470000000743013213443214014767 0ustar debiandebian cassiopee-c-1.0.7/.project0000644000174700017470000000145213213443214014622 0ustar debiandebian Cassiopee org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder full,incremental, org.eclipse.cdt.core.cnature org.eclipse.cdt.core.ccnature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.managedbuilder.core.ScannerConfigNature cassiopee-c-1.0.7/README.md0000644000174700017470000000373113213443214014434 0ustar debiandebiancassiopee-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.7/Changelog0000644000174700017470000000130513213443214014762 0ustar debiandebian1.0.7: 11/12/17 O. Sallou - bug fix, last character was not indexed 1.0.6: 26/10/17 O. Sallou - Fix search with tree reduction, closes #1 1.0.5: 18/11/16 O. Sallou - bug fix in search with reduction 1.0.4: 08/04/16 O. Sallou - bug fix in search with reduction 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.7/.gitignore0000644000174700017470000000056513213443214015147 0ustar debiandebiantest/*.idx test/*.meta test/test.out # 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.7/LICENSE0000644000174700017470000000017313213443214014157 0ustar debiandebianLicense: GNU GPL-3+ Full text is available at http://www.gnu.org/licenses/gpl-3.0.html Copyright (c) 2013 Olivier Sallou