source: branches/port5/PROBE/PT_findEx.cxx

Last change on this file was 5350, checked in by westram, 17 years ago
  • fixed use of GBS_strstruct functions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4// #include <malloc.h>
5
6#include <PT_server.h>
7#include <PT_server_prototypes.h>
8#include "probe.h"
9#include "probe_tree.hxx"
10#include "pt_prototypes.h"
11
12static bool findLeftmostProbe(POS_TREE *node, char *probe, int restlen, int height) {
13    if (restlen==0) return true;
14
15    switch (PT_read_type(node)) {
16        case PT_NT_NODE:  {
17            for (int i=PT_A; i<PT_B_MAX; ++i) {
18                POS_TREE *son = PT_read_son(psg.ptmain, node, PT_BASES(i));
19                if (son) {
20                    probe[0] = PT_BASES(i); // write leftmost probe into result
21                    bool found = findLeftmostProbe(son, probe+1, restlen-1, height+1);
22                    pt_assert(!found || (strlen(probe) == (size_t)restlen));
23                    if (found) return true;
24                }
25            }
26            break;
27        }
28        case PT_NT_CHAIN: {
29            // fprintf(stdout, "Reached chain in findLeftmostProbe() (restlen=%i)\n", restlen);
30            pt_assert(0);  // unhandled yet
31            break;
32        }
33        case PT_NT_LEAF:  {
34            // here the probe-tree is cut off, because only one species matches
35            int pos  = PT_read_rpos(psg.ptmain, node) + height;
36            int name = PT_read_name(psg.ptmain, node);
37            if (pos + restlen >= psg.data[name].size)
38                break;          // at end-of-sequence -> no probe with wanted length here
39
40            pt_assert(probe[restlen] == 0);
41            const char *seq_data = psg.data[name].data;
42            for (int r = 0; r<restlen; ++r) {
43                int data = seq_data[pos+r];
44                if (data == PT_QU || data == PT_N) return false; // ignore probes that contain 'N' or '.'
45                probe[r] = data;
46            }
47            pt_assert(probe[restlen] == 0);
48            pt_assert(strlen(probe) == (size_t)restlen);
49            return true;
50        }
51        default : pt_assert(0); break; // oops
52    }
53
54    return false;
55}
56//  ---------------------------------------------------------------------
57//      static bool findNextProbe(POS_TREE *node, char *probe, int restlen)
58//  ---------------------------------------------------------------------
59// searches next probe after 'probe' ('probe' itself may not exist)
60// returns: true if next probe was found
61// 'probe' is modified to next probe
62static bool findNextProbe(POS_TREE *node, char *probe, int restlen, int height) {
63    if (restlen==0) return false;  // in this case we found the recent probe
64    // returning false upwards takes the next after
65
66    switch (PT_read_type(node)) {
67        case PT_NT_NODE:  {
68            POS_TREE *son   = PT_read_son(psg.ptmain, node, PT_BASES(probe[0]));
69            bool      found = (son != 0) && findNextProbe(son, probe+1, restlen-1, height+1);
70
71            pt_assert(!found || (strlen(probe) == (size_t)restlen));
72
73            if (!found) {
74                for (int i=probe[0]+1; !found && i<PT_B_MAX; ++i) {
75                    son = PT_read_son(psg.ptmain, node, PT_BASES(i));
76                    if (son) {
77                        probe[0] = PT_BASES(i); // change probe
78                        found = findLeftmostProbe(son, probe+1, restlen-1, height+1);
79                        pt_assert(!found || (strlen(probe) == (size_t)restlen));
80                    }
81                }
82            }
83            return found;
84        }
85        case PT_NT_CHAIN:
86        case PT_NT_LEAF:  {
87            // species list or single species reached
88            // fprintf(stdout, "Reached chain or leaf in findNextProbe() (restlen=%i)\n", restlen);
89            return false;
90        }
91        default : pt_assert(0); break; // oops
92    }
93
94    pt_assert(0);
95    return false;
96}
97
98//  ------------------------------------------------------
99//      extern "C" int PT_find_exProb(PT_exProb *pep)
100//  ------------------------------------------------------
101extern "C" int PT_find_exProb(PT_exProb *pep) {
102    POS_TREE      *pt      = psg.pt; // start search at root
103    GBS_strstruct *gbs_str = GBS_stropen(pep->numget*(pep->plength+1)+1);
104    bool           first   = true;
105
106    for (int c=0; c<pep->numget; ++c) {
107        bool found = false;
108
109        if (pep->restart) {
110            pep->restart = 0;
111
112            char *probe = (char*)malloc(pep->plength+1);
113            memset(probe, 'N', pep->plength);
114            probe[pep->plength] = 0; // EOS marker
115
116            compress_data(probe);
117
118            pep->next_probe.data = probe;
119            pep->next_probe.size = pep->plength+1;
120
121            found = findLeftmostProbe(pt, pep->next_probe.data, pep->plength, 0);
122
123            pt_assert(pep->next_probe.data[pep->plength] == 0);
124            pt_assert(strlen(pep->next_probe.data) == (size_t)pep->plength);
125        }
126
127        if (!found) {
128            found = findNextProbe(pt, pep->next_probe.data, pep->plength, 0);
129
130            pt_assert(pep->next_probe.data[pep->plength] == 0);
131            pt_assert(strlen(pep->next_probe.data) == (size_t)pep->plength);
132        }
133        if (!found) break;
134
135        // append the probe to the probe list
136
137        if (!first) GBS_strcat(gbs_str, ";");
138        first = false;
139        GBS_strcat(gbs_str, pep->next_probe.data);
140    }
141
142    pep->result = GBS_strclose(gbs_str);
143
144    return 0;
145}
146
Note: See TracBrowser for help on using the repository browser.