1 ///A tutorial showing how to extent an index with a node predicate.
2 #include <iostream>
3 #include <seqan/index.h>
4 
5 using namespace seqan;
6 
7 /// constraint parameters
8 struct TMyConstraints {
9 	double p_min;
10 	unsigned int replen_max;
11 	bool _cachedPred;
12 };
13 
14 /// SeqAn extensions
15 namespace seqan
16 {
17 	// custom TSpec for our customized wotd-Index
18 	struct TMyIndex;
19 
20 	template <typename TText>
21 	struct Cargo<Index<TText, IndexWotd<TMyIndex> > > {
22 		typedef TMyConstraints Type;
23 	};
24 
25 	// node predicate
26 	template <typename TText, typename TSpec>
nodePredicate(Iter<Index<TText,IndexWotd<TMyIndex>>,TSpec> & it)27 	bool nodePredicate(Iter<Index<TText, IndexWotd<TMyIndex> >, TSpec> &it)
28 	{
29 		TMyConstraints &cons = cargo(container(it));
30 		unsigned int delta = countSequences(container(it)) * repLength(it);
31 		unsigned int textLen = length(container(it));
32 
33 		if (textLen <= delta) return cons._cachedPred = true;
34 		return cons._cachedPred =
35 			((double)countOccurrences(it) / (double)(textLen - delta)) > cons.p_min;
36 	}
37 
38 	// monotonic hull
39 	template <typename TText, typename TSpec>
nodeHullPredicate(Iter<Index<TText,IndexWotd<TMyIndex>>,TSpec> & it)40 	bool nodeHullPredicate(Iter<Index<TText, IndexWotd<TMyIndex> >, TSpec> &it)
41 	{
42 		TMyConstraints const &cons = cargo(container(it));
43 		unsigned int textLen = length(container(it));
44 
45 		if (repLength(it) > cons.replen_max) return false;
46 
47 		unsigned int delta = countSequences(container(it)) * cons.replen_max;
48 		if (textLen <= delta) return true;
49 		return ((double)countOccurrences(it) /
50 				(double)(textLen - delta)) > cons.p_min;
51 	}
52 }
53 
main()54 int main ()
55 {
56 ///We begin with a @Class.String@ to store our sequence.
57 	String<char> myString = "How many wood would a woodchuck chuck.";
58 
59 ///Then we create our customized index which is a specialization
60 ///of the deferred @Class.Index.wotd-Index@
61 	typedef Index< String<char>, IndexWotd<TMyIndex> > TMyIndex;
62 	TMyIndex myIndex(myString);
63 
64 	cargo(myIndex).replen_max = 10;
65 	cargo(myIndex).p_min = 0.05;
66 
67 ///To find all strings that fulfill our constraints,
68 ///we simply do a dfs-traversal via @Function.goBegin@ and @Function.goNext@.
69 	typedef Iterator< TMyIndex, TopDown<ParentLinks<> > >::Type TConstrainedIterator;
70 	TConstrainedIterator myConstrainedIterator(myIndex);
71 
72 	goBegin(myConstrainedIterator);
73 	while (!atEnd(myConstrainedIterator))
74 	{
75 
76 ///@Function.countOccurrences@ returns the number of hits of the representative.
77 		::std::cout << countOccurrences(myConstrainedIterator) << "x  ";
78 
79 ///The representative string can be determined with @Function.representative@
80 		::std::cout << "\t\"" << representative(myConstrainedIterator) << '\"' << ::std::endl;
81 
82 		goNext(myConstrainedIterator);
83 	}
84 
85 	return 0;
86 }
87