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