source: tags/svn.1.5.4/PROBE/PT_etc.cxx

Last change on this file was 8313, checked in by westram, 12 years ago
  • removed dead code

(partly reverted by [8316])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : PT_etc.cxx                                        //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "probe.h"
12
13#include <PT_server_prototypes.h>
14#include "pt_prototypes.h"
15#include <struct_man.h>
16#include <arb_strbuf.h>
17
18void set_table_for_PT_N_mis(int ignored_Nmismatches, int when_less_than_Nmismatches) {
19    // calculate table for PT_N mismatches
20    //
21    // 'ignored_Nmismatches' specifies, how many N-mismatches will be accepted as
22    // matches, when overall number of N-mismatches is below 'when_less_than_Nmismatches'.
23    //
24    // above that limit, every N-mismatch counts as mismatch
25
26    if ((when_less_than_Nmismatches-1)>PT_POS_TREE_HEIGHT) when_less_than_Nmismatches = PT_POS_TREE_HEIGHT+1;
27    if (ignored_Nmismatches >= when_less_than_Nmismatches) ignored_Nmismatches = when_less_than_Nmismatches-1;
28
29    psg.w_N_mismatches[0] = 0;
30    int mm;
31    for (mm = 1; mm<when_less_than_Nmismatches; ++mm) {
32        psg.w_N_mismatches[mm] = mm>ignored_Nmismatches ? mm-ignored_Nmismatches : 0;
33    }
34    pt_assert(mm <= (PT_POS_TREE_HEIGHT+1));
35    for (; mm <= PT_POS_TREE_HEIGHT; ++mm) {
36        psg.w_N_mismatches[mm] = mm;
37    }
38}
39
40void pt_export_error(PT_local *locs, const char *error) {
41    freedup(locs->ls_error, error);
42}
43
44static const gene_struct *get_gene_struct_by_internal_gene_name(const char *gene_name) {
45    gene_struct to_search(gene_name, "", "");
46
47    gene_struct_index_internal::const_iterator found = gene_struct_internal2arb.find(&to_search);
48    return (found == gene_struct_internal2arb.end()) ? 0 : *found;
49}
50static const gene_struct *get_gene_struct_by_arb_species_gene_name(const char *species_gene_name) {
51    const char *slash = strchr(species_gene_name, '/');
52    if (!slash) {
53        fprintf(stderr, "Internal error: '%s' should be in format 'organism/gene'\n", species_gene_name);
54        return 0;
55    }
56
57    int   slashpos     = slash-species_gene_name;
58    char *organism     = strdup(species_gene_name);
59    organism[slashpos] = 0;
60
61    gene_struct to_search("", organism, species_gene_name+slashpos+1);
62    free(organism);
63
64    gene_struct_index_arb::const_iterator found = gene_struct_arb2internal.find(&to_search);
65    return (found == gene_struct_arb2internal.end()) ? 0 : *found;
66}
67
68static const char *arb2internal_name(const char *name) {
69    // convert arb name ('species/gene') into internal shortname
70    const gene_struct *found = get_gene_struct_by_arb_species_gene_name(name);
71    return found ? found->get_internal_gene_name() : 0;
72}
73
74const char *virt_name(PT_probematch *ml) 
75{
76    // get the name with a virtual function
77    if (gene_flag) {
78        const gene_struct *gs = get_gene_struct_by_internal_gene_name(psg.data[ml->name].get_name());
79        return gs ? gs->get_arb_species_name() : "<cantResolveName>";
80    }
81    else {
82        pt_assert(psg.data[ml->name].get_name());
83        return psg.data[ml->name].get_name();
84    }
85}
86
87const char *virt_fullname(PT_probematch * ml) 
88{
89    if (gene_flag) {
90        const gene_struct *gs = get_gene_struct_by_internal_gene_name(psg.data[ml->name].get_name());
91        return gs ? gs->get_arb_gene_name() : "<cantResolveGeneFullname>";
92    }
93    else {
94        return psg.data[ml->name].get_fullname() ?  psg.data[ml->name].get_fullname() : "<undefinedFullname>";
95    }
96}
97
98#define MAX_LIST_PART_SIZE 50
99
100static const char *get_list_part(const char *list, int& offset) {
101    // scans strings with format "xxxx#yyyy#zzzz"
102    // your first call should be with offset == 0
103    //
104    // returns : static copy of each part or 0 when done
105    // offset is incremented by this function and set to -1 when all parts were returned
106
107    static char buffer[2][MAX_LIST_PART_SIZE+1];
108    static int  curr_buff = 0;  // toggle buffer to allow 2 parallel gets w/o invalidation
109
110    if (offset<0) return 0;     // already done
111    curr_buff ^= 1; // toggle buffer
112
113    const char *numsign = strchr(list+offset, '#');
114    int         num_offset;
115    if (numsign) {
116        num_offset = numsign-list;
117        pt_assert(list[num_offset] == '#');
118    }
119    else { // last list part
120        num_offset = offset+strlen(list+offset);
121        pt_assert(list[num_offset] == 0);
122    }
123
124    // now num_offset points to next '#' or to end-of-string
125
126    int len = num_offset-offset;
127    pt_assert(len <= MAX_LIST_PART_SIZE);
128
129    memcpy(buffer[curr_buff], list+offset, len);
130    buffer[curr_buff][len] = 0; // EOS
131
132    offset = (list[num_offset] == '#') ? num_offset+1 : -1; // set offset for next part
133
134    return buffer[curr_buff];
135}
136
137#undef MAX_LIST_PART_SIZE
138
139char *ptpd_read_names(PT_local *locs, const char *names_list, const char *checksums, const char*& error) {
140    /* read the name list separated by '#' and set the flag for the group members,
141     + returns a list of names which have not been found
142     */
143
144    // clear 'is_group'
145    for (int i = 0; i < psg.data_count; i++) {
146        psg.data[i].set_group_state(0); // Note: probes are designed for species with is_group == 1
147    }
148    locs->group_count = 0;
149    error             = 0;
150
151    if (!names_list) {
152        error = "Can't design probes for no species (species list is empty)";
153        return 0;
154    }
155
156    int noff = 0;
157    int coff = 0;
158
159    GBS_strstruct *not_found = 0;
160
161    while (noff >= 0) {
162        pt_assert(coff >= 0);   // otherwise 'checksums' contains less elements than 'names_list'
163        const char *arb_name      = get_list_part(names_list, noff);
164        const char *internal_name = arb_name; // differs only for gene pt server
165
166        if (arb_name[0] == 0) {
167            pt_assert(names_list[0] == 0);
168            break; // nothing marked
169        }
170
171        if (gene_flag) {
172            const char *slash = strchr(arb_name, '/');
173
174            if (!slash) {
175                // ARB has to send 'species/gene'.
176                // If it did not, user did not mark 'Gene probes ?' flag
177
178                error = GBS_global_string("Expected '/' in '%s' (this PT-server can only design probes for genes)", arb_name);
179                break;
180            }
181
182            internal_name = arb2internal_name(arb_name);
183            pt_assert(internal_name);
184        }
185
186        int  idx   = GBS_read_hash(psg.namehash, internal_name);
187        bool found = false;
188
189        if (idx) {
190            --idx;              // because 0 means not found!
191
192            if (checksums) {
193                const char *checksum = get_list_part(checksums, coff);
194                // if sequence checksum changed since pt server was updated -> not found
195                found                = atol(checksum) == psg.data[idx].get_checksum();
196            }
197            else {
198                found = true;
199            }
200
201            if (found) {
202                psg.data[idx].set_group_state(1); // mark
203                locs->group_count++;
204            }
205        }
206
207        if (!found) { // name not found -> put into result
208            if (not_found == 0) not_found = GBS_stropen(1000);
209            else GBS_chrcat(not_found, '#');
210            GBS_strcat(not_found, arb_name);
211        }
212    }
213
214    char *result = not_found ? GBS_strclose(not_found) : 0;
215    if (error) freenull(result);
216    return result;
217}
218
219bytestring *PT_unknown_names(PT_pdc *pdc) {
220    static bytestring un = { 0, 0 };
221    PT_local *locs = (PT_local*)pdc->mh.parent->parent;
222    delete un.data;
223
224    const char *error;
225    un.data = ptpd_read_names(locs, pdc->names.data, pdc->checksums.data, error);
226    if (un.data) {
227        un.size = strlen(un.data) + 1;
228        pt_assert(!error);
229    }
230    else {
231        un.data = strdup("");
232        un.size = 1;
233        if (error) pt_export_error(locs, error);
234    }
235    return &un;
236}
237
238void PT_init_base_string_counter(char *str, char initval, int size)
239{
240    memset(str, initval, size+1);
241    str[size] = 0;
242}
243
244void PT_inc_base_string_count(char *str, char initval, char maxval, int size)
245{
246    int i;
247    if (!size) {
248        str[0]=255;
249        return;
250    }
251    for (i=size-1; i>=0; i--) {
252        str[i]++;
253        if (str[i] >= maxval) {
254            str[i] = initval;
255            if (!i) str[i]=255; // end flag
256        }
257        else {
258            break;
259        }
260    }
261}
Note: See TracBrowser for help on using the repository browser.