source: tags/initial/ORS_CGI/ORS_C_java.cxx

Last change on this file was 2, checked in by oldcode, 23 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.2 KB
Line 
1/*
2#######################################
3#                                     #
4#    ORS_CLIENT:  JAVA                #
5#    communication with java applet   #
6#                                     #
7####################################### */
8
9#include <stdio.h>
10#include <string.h>
11#include <memory.h>
12#include <malloc.h>
13#include <arbdb.h>
14#include <arbdbt.h>
15
16#include <ors_client.h>
17#include <client.h>
18
19#include <cat_tree.hxx>
20#include "ors_c_java.hxx"
21#include "ors_c.hxx"
22#include "ors_c_proto.hxx"
23
24FILE *t2j_out;  // output file
25CAT_tree *cat_tree = NULL;      // the tree
26FILE *t2j_debug;
27
28T2J_transfer_struct::T2J_transfer_struct(long size, enum CAT_FIELDS key_indexi) {
29        memset((char *)this,0,sizeof(T2J_transfer_struct));
30        nitems = size;
31        items = (T2J_item *)calloc(sizeof(T2J_item),(int)size);
32        this->key_index = key_indexi;
33}
34
35/***********************************************************************
36                To output stream: nibbles bytes and integers
37***********************************************************************/
38int t2j_last_nibble  = -1;
39
40GB_INLINE void t2j_write_nibble(int value){
41        if (t2j_last_nibble<0) {
42                t2j_last_nibble = value;
43        }else{
44                int o = t2j_last_nibble<<4 | value;
45                fputc(o,t2j_out);
46                t2j_last_nibble = -1;
47        }
48}
49
50GB_INLINE void t2j_flush_nibble(void){
51        if (t2j_last_nibble>=0) {
52                int o = t2j_last_nibble<<4 | 15;
53                fputc(o,t2j_out);
54                t2j_last_nibble = -1;
55        }       
56}
57
58int t2j_last_bit_string = 0;
59int t2j_bits_already_in_c = 0;
60
61GB_INLINE void t2j_flush_bits(void){
62        fputc(t2j_last_bit_string,t2j_out);
63        t2j_last_bit_string = 0;
64        t2j_bits_already_in_c = 0;
65}
66
67GB_INLINE void t2j_write_bit(int bit){
68        if (bit) {
69                t2j_last_bit_string |=  0x80 >> t2j_bits_already_in_c;
70        }
71        if ((++t2j_bits_already_in_c) >=8) {
72                t2j_flush_bits();
73        }
74}
75
76
77void t2j_write_byte(int value){
78        t2j_flush_nibble();
79        fputc(value,t2j_out);
80}
81
82char *t2j_write_int2(unsigned int value){
83        register int i;
84        i = (value >>24) & 0xff; t2j_write_byte(i);
85        i = (value >>16) & 0xff; t2j_write_byte(i);
86        i = (value >>8) & 0xff; t2j_write_byte(i);
87        i = (value >>0) & 0xff; t2j_write_byte(i);
88        return 0;
89}
90
91char *t2j_write_uint(unsigned int value, int or_cmd){
92        t2j_write_nibble(0);            // attention
93        register int i;
94        if (value >= 0x1000000) {
95                t2j_write_nibble(4 | or_cmd);           // how many bytes !!!!
96                i = (value >>24) & 0xff; t2j_write_byte(i);
97                i = (value >>16) & 0xff; t2j_write_byte(i);
98                i = (value >>8) & 0xff; t2j_write_byte(i);
99                i = (value >>0) & 0xff; t2j_write_byte(i);
100        }else if (value > 0x1000) {
101                t2j_write_nibble(3 | or_cmd);
102                i = (value >>16) & 0xff; t2j_write_byte(i);
103                i = (value >>8) & 0xff; t2j_write_byte(i);
104                i = (value >>0) & 0xff; t2j_write_byte(i);
105        }else if (value > 0x100){
106                t2j_write_nibble(2 | or_cmd);
107                i = (value >>8) & 0xff; t2j_write_byte(i);
108                i = (value >>0) & 0xff; t2j_write_byte(i);
109        }else{
110                t2j_write_nibble(1 | or_cmd);
111                i = (value >>0) & 0xff; t2j_write_byte(i);
112        }
113        return 0;
114}
115
116/***********************************************************************
117        Sends the data in nodes->user_data to the java programm
118        modifier_string is just send after the main header
119        Sideeffects:    writes to t2j_out
120                        uses cat_tree
121***********************************************************************/
122
123struct t2j_s1_item {
124        CAT_node_id id;
125        struct t2j_s1_item *next;
126};
127
128struct t2j_s1_item_header {
129        struct t2j_s1_item *first;
130        struct t2j_s1_item *last;
131        char    *value;
132        long    focus_members;
133        long    members;
134        long    estimated_transfer_size;                // very rough idea !!!
135};
136
137CAT_node_id t2j_get_focus_right_bound(CAT_node_id focus){
138        while (cat_tree->nodes[focus].rightson) {
139                focus = cat_tree->nodes[focus].rightson;
140        }
141        return focus;
142}
143
144/***********************************************************************
145        Compare Function to sort the result list,
146        The idea is that data within the focus is transferred first,
147        followed by data with a lot of hits
148        Sideeffects: sorts an void ** array
149***********************************************************************/
150long t2j_compare_two_hitems(struct t2j_s1_item_header *hi0, struct t2j_s1_item_header *hi1){
151        double l = (hi0->focus_members + hi0->members/20) / hi0->estimated_transfer_size;
152        double r = (hi1->focus_members + hi1->members/20) / hi1->estimated_transfer_size;
153        if (l>r) return 1;
154        return -1;
155}
156
157long t2j_compare_two_ids(long i1, long i2) {
158        if (i1 < i2) return -1;
159        return 1;
160}
161
162void t2j_write_range(int start_of_range, int end_of_range){
163        int rsize = end_of_range - start_of_range;
164        if (rsize == 1) {               // no range !!!
165                t2j_write_nibble(rsize);
166        }else{
167                if (rsize >= 15) {
168                        t2j_write_uint(rsize,8);
169                }else{
170                        t2j_write_nibble(15);
171                        t2j_write_nibble(rsize);
172                }
173        }
174}
175
176void t2j_indexlist_2_OTF(long *buffer, long buf_size){
177        int j;
178        int start_of_range, end_of_range;
179        start_of_range = end_of_range = -1;
180
181        GB_mergesort((void **)buffer,0,buf_size,
182        (long (* )(void *, void *, char *cd ))t2j_compare_two_ids,0);
183
184        for (j = 0; j < buf_size; j++) {
185                int id = (int) buffer[j];
186                if (id == end_of_range + 1){            // resize range
187                        end_of_range++;
188                }else{
189                                                        // write out range !!!
190                        if (end_of_range > start_of_range){
191                                t2j_write_range(start_of_range,end_of_range);
192                        }
193                        int rsize = (int)id - end_of_range;
194                        if (rsize >= 15) {
195                                t2j_write_uint(rsize,0);
196                        }else{
197                                t2j_write_nibble(rsize);
198                        }
199                        start_of_range = end_of_range = (int)id;
200                }
201        }
202        if (end_of_range > start_of_range){             // last range
203                t2j_write_range(start_of_range,end_of_range);
204        }
205
206        t2j_write_nibble(0);
207        t2j_write_nibble(0);
208        t2j_flush_nibble();                     // back to byte boundary !!!
209}
210
211/***********************************************************************
212        Send all information stored in cat_tree->nodes[xx].user_data
213***********************************************************************/
214GB_ERROR T2J_send_tree(CAT_node_id focus, char *modifier_string){
215        struct t2j_s1_item_header **hitems =
216                (struct t2j_s1_item_header **)calloc(sizeof(struct t2j_s1_item_header *),
217                        (int)cat_tree->nnodes); // nnodes is the very worst case !!!
218        if (focus <0 || focus >= cat_tree->nnodes) focus = 0;
219        int     header_in_use = 0;
220        CAT_node_id     left_focus = focus;
221        CAT_node_id     right_focus = t2j_get_focus_right_bound(focus);
222        GB_HASH *convert_hash = GBS_create_hash(cat_tree->nnodes,0);
223        CAT_node_id i;
224
225                // ********* collect the answer in a hash table
226        for (i=0; i<cat_tree->nnodes; i++){
227                CAT_node *node = & cat_tree->nodes[i];
228                char *s = node->user_data;
229                if (!s) continue;
230                struct t2j_s1_item *item = (struct t2j_s1_item *)
231                        calloc(sizeof(struct t2j_s1_item),1);
232                item->id = i;
233                struct t2j_s1_item_header *hitem =
234                        (struct t2j_s1_item_header *)GBS_read_hash(convert_hash, s);
235                if (!hitem) {
236                        hitem = (struct t2j_s1_item_header *)
237                                calloc(sizeof(struct t2j_s1_item_header),1);
238                        hitems[header_in_use++] = hitem;
239                        hitem ->first = hitem->last = item;
240                        hitem->estimated_transfer_size = strlen(s)+5;
241                        hitem->value = s;
242                        GBS_write_hash_no_strdup(convert_hash,s,(long)hitem);
243                }else{
244                        if (hitem->last->id != i-1) {
245                                hitem->estimated_transfer_size += 1;
246                        }
247                        hitem->last->next = item;
248                        hitem->last = item;
249                }
250                hitem->members++;
251                if (i >= left_focus && i <= right_focus) hitem->focus_members++;
252        }
253                // ***** sort it by quality
254        GB_mergesort((void **)hitems,0,header_in_use,
255                (long (* )(void *, void *, char *cd ))t2j_compare_two_hitems,0);
256
257        CAT_NUMBERING numbering = CAT_NUMBERING_LEVELS;
258        fputc(T2J_LEVEL_INDEXING,t2j_out);      // Write OTF tag
259        t2j_write_int2(header_in_use);          // number of items
260
261        if (modifier_string) {
262                if (!fwrite(modifier_string, strlen(modifier_string) +1, 1, t2j_out)){
263                        return GB_export_error("Cannot write to out");
264                }
265        }
266        // TODO: HIER NOCH EIN UNBEDINGTES "begin" anhaengen!
267
268        for (i = 0; i< header_in_use; i++) {    // go through all values
269                struct t2j_s1_item_header *hitem = hitems[i];
270                int     redo_needed;
271                struct t2j_s1_item *item;
272                long *buffer = (long *)calloc(sizeof(long) , (int)hitem->members);
273                char color_tab[256];                            // already sent color info
274                int j;
275                for (j=0;j<256;j++) color_tab[j] = 0;           // nothing has been sent yet
276                struct t2j_s1_item *ref_item;
277                for (ref_item = hitem->first; ref_item; ref_item = ref_item->next) {
278                        CAT_node *node = & cat_tree->nodes[ref_item->id];
279                        int color = node->color;
280                        int grouped = node->is_grouped;
281                        int col_ref = grouped | (color<<4);
282                        if (color_tab[col_ref]) continue;               // has already been sent
283                        color_tab[col_ref] = 1;                         // is to be sent
284                        t2j_write_byte(col_ref);
285                        redo_needed = 0;
286                        fwrite(hitem->value, strlen(hitem->value)+1, 1, t2j_out);
287
288                        for (j=0, item = ref_item; item; item = item->next) {
289                                CAT_node *node = & cat_tree->nodes[item->id];
290                                if (node->is_grouped != grouped || node->color != color) {
291                                        redo_needed = 1;
292                                        continue;
293                                }
294                                buffer[j++] = cat_tree->nodes[item->id].numbering[numbering];
295                        }
296                        t2j_indexlist_2_OTF(buffer,j );
297                        if (!redo_needed) break;
298                }
299
300                delete buffer;
301
302        }
303        return 0;
304}
305
306/***********************************************************************
307        Transform any query list to OTF
308        Sideeffects: no !!!!
309***********************************************************************/
310GB_ERROR T2J_transform(char *path_of_tree, char *modifier_string, 
311                struct T2J_transfer_struct *data, 
312                CAT_node_id focus, FILE *out){
313        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);
314        if (!cat_tree) return GB_get_error();
315        t2j_out = out;
316        GB_HASH *index = GBS_create_hash(cat_tree->nnodes,0);
317        int i;
318                        // create the index !!!!!!!!!!!!
319        for (i=0;i< cat_tree->nnodes;i++) {
320                if (cat_tree->nodes[i].field_offsets[data->key_index]) {
321                        GBS_write_hash_no_strdup(index,cat_tree->data +
322                                cat_tree->nodes[i].field_offsets[data->key_index],i+1);
323                }else   if (cat_tree->nodes[i].field_offsets[CAT_FIELD_GROUP_NAME]) {
324                        GBS_write_hash_no_strdup(index,cat_tree->data +
325                                cat_tree->nodes[i].field_offsets[CAT_FIELD_GROUP_NAME],i+1);
326                }
327        }
328
329
330        for (i=0;i<data->nitems;i++) {
331                long ind = GBS_read_hash(index, data->items[i].key);
332                if (!ind) continue;
333                ind -= 1;
334                cat_tree->nodes[ind].color = data->items[i].color;
335                cat_tree->nodes[ind].user_data = data->items[i].value;
336        }
337        return T2J_send_tree(focus, modifier_string);
338}
339
340/***********************************************************************
341        Send the tree.   A '1' bit indicates a node '0' a leaf
342        Sideeffects: writes to out
343***********************************************************************/
344GB_ERROR T2J_send_bit_coded_tree(char *path_of_tree, FILE *out){
345        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree); // 3 lines that should never be deleted
346        if (!cat_tree) return GB_get_error();
347        t2j_out = out;
348
349        int i;
350        t2j_write_uint(cat_tree->nnodes,0);
351        for (i=0;i<cat_tree->nnodes;i++){
352                CAT_node *node = & cat_tree->nodes[i];
353                if (node->leftson) {
354                        t2j_write_bit(1);
355                }else{
356                        t2j_write_bit(0);
357                }
358        }
359        t2j_flush_bits();
360        return 0;
361}
362
363void t2j_send_newick_rek(CAT_node *node, FILE *out){
364    const char *name = 0;
365    {
366        int n_offset = node->field_offsets[CAT_FIELD_NAME];
367        if (n_offset){
368            name = & cat_tree->data[n_offset];
369        }
370    }
371    if (!node->leftson){        // leaf
372        if (name){
373            fprintf(out,"'%s':%i",name,ode->branch_length);
374        }
375        return;
376    }
377    fprintf(out,"(");
378    t2j_send_newick_rek(cat_tree->nodes[node->leftson],out);
379    fprintf(out,",");
380    t2j_send_newick_rek(cat_tree->nodes[node->rightson],out);
381    if (name){
382        fprintf(out,")'%s':%i",name,ode->branch_length);
383    }else{
384        fprintf(out,"):%i",ode->branch_length);
385    }
386}
387   
388GB_ERROR T2J_send_newick_tree(char *path_of_tree, FILE *out){
389    if (!cat_tree)      cat_tree = load_CAT_tree(path_of_tree); // 3 lines that should never be deleted
390    if (!cat_tree) return GB_get_error();
391    t2j_out = out;
392    fprintf(out,"[%i]\n",cat_tree->nnodes);
393    t2j_send_newick_rek(&cat_tree->nodes[0],out);
394    fprintf(out,"\n");
395    return 0;
396}
397
398   
399/***********************************************************************
400        Send the tree.   level numbering !!! branch lengths from 0-15
401        Sideeffects: writes to out
402***********************************************************************/
403CAT_node_id *t2j_mcreate_level_indexing(void){
404        static CAT_node_id *ids = NULL;
405        if (ids) return ids;
406        ids = (CAT_node_id *)calloc(sizeof(CAT_node_id), cat_tree->nnodes);
407        int i;
408        for (i=0;i< cat_tree->nnodes;i++) {
409                ids[cat_tree->nodes[i].numbering[CAT_NUMBERING_LEVELS]] = i;
410        }
411        return ids;
412}
413
414GB_ERROR T2J_send_branch_lengths(char *path_of_tree, FILE *out){
415        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);         // 3 lines that should never be deleted
416        if (!cat_tree) return GB_get_error();
417        t2j_out = out;
418        CAT_node_id *ids = t2j_mcreate_level_indexing();
419        int i;
420        for (i=0;i<cat_tree->nnodes;i++){
421                CAT_node *node = & cat_tree->nodes[ids[i]];
422                int bl = node->branch_length;
423                if (bl>=16) bl = 15;
424                t2j_write_nibble(bl);
425        }
426        delete ids;
427        t2j_flush_nibble();
428        return 0;
429}
430
431/***********************************************************************
432        Read a file into the transfer struct:
433        File Syntax: id#value\nid#value\n....
434***********************************************************************/
435struct T2J_transfer_struct *T2J_read_query_result_from_data(char *data,CAT_FIELDS catfield){
436        int nls = 0;
437        char *p;
438        for (p = data; p ; p = strchr(p+1,'\n')) nls++;
439        T2J_transfer_struct *transfer = new T2J_transfer_struct(nls,catfield);
440        nls = 0;
441        char *np;
442        char ascii_2_col[256];
443        memset(ascii_2_col,T2J_COLOR_UNKNOWN,256);
444        ascii_2_col['+'] = T2J_COLOR_YES;
445        ascii_2_col['p'] = T2J_COLOR_YES;
446        ascii_2_col['1'] = T2J_COLOR_YES;
447        ascii_2_col['-'] = T2J_COLOR_NO;
448        ascii_2_col['n'] = T2J_COLOR_NO;
449        ascii_2_col['0'] = T2J_COLOR_NO;
450        for (p = data; p ; p = np) {
451                np = strchr(p,'\n');
452                if (np) *(np++) = 0;
453
454                char *col = strchr(p,'#');      // color
455                if (!col) continue;
456                *(col++) = 0;
457
458                char *val = strchr(col,'#');    // value
459                if (!val) continue;
460                *(val++) = 0;
461                while ( *p == ' ') p++;         // remove leading spaces
462                while ( *val == ' ') val++;
463                transfer->items[nls].key = p;
464                transfer->items[nls].color = ascii_2_col[col[0]];
465                transfer->items[nls].value = val;
466                nls++;
467        }
468        transfer->nitems = nls;
469        return transfer;
470}
471/***********************************************************************
472        Read a string from pt_server into the transfer struct:
473        File Syntax: dummy\1id\1value\1id\1value...\0
474***********************************************************************/
475struct T2J_transfer_struct *T2J_read_query_result_from_pts(char *data){
476        int nls = 0;
477        char *p;
478        for (p = data; p ; p = strchr(p+1,1)) nls++;
479        T2J_transfer_struct *transfer = new T2J_transfer_struct(nls/2+1,CAT_FIELD_NAME);
480        nls = 0;
481        char *start = strchr(data,1);
482        if(!start) {
483                GB_export_error("No hits");
484                return 0;
485        }
486        char *next;
487        for ( start++; start; start=next ) {
488                char *info = strchr(start,1);
489                if (!info) break;
490                *info=0;
491                info++;
492                next = strchr(info,1);
493                if (next) *(next++) = 0;
494                transfer->items[nls].key = start;
495                transfer->items[nls].color = T2J_COLOR_YES;
496                transfer->items[nls].value = info;
497                nls++;
498        }
499        transfer->nitems = nls;
500        return transfer;
501}
502/***********************************************************************
503        Read a file into the transfer struct:
504        File Syntax: id#value\nid#value\n....
505***********************************************************************/
506struct T2J_transfer_struct *T2J_read_query_result_from_file(char *path,CAT_FIELDS catfield){
507        char *data = GB_read_file(path);
508        if (!data) {
509                GB_export_error("Cannot open datafile '%s'",path);
510                return 0;
511        }
512        return T2J_read_query_result_from_data(data,catfield);
513}
514/***********************************************************************
515        Transfer the first word of the full_name ...
516***********************************************************************/
517GB_ERROR T2J_transfer_fullnames1(char *path_of_tree,FILE *out) {
518        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);         // 3 lines that should never be deleted
519        if (!cat_tree) return GB_get_error();
520        t2j_out = out;
521
522        int i;
523        for (i=0;i<cat_tree->nnodes;i++){
524                CAT_node *node = & cat_tree->nodes[i];
525                if (node->field_offsets[CAT_FIELD_FULL_NAME]) {
526                        node->user_data = cat_tree->data + node->field_offsets[CAT_FIELD_FULL_NAME];
527                        char *sep = strchr(node->user_data,' ');
528                        if (sep) *sep = 0;
529                }
530                node->color = node->color_in;
531        }
532        return T2J_send_tree(0,0);
533}
534
535/***********************************************************************
536        Transfer the rest word of the full_name ...
537***********************************************************************/
538GB_ERROR T2J_transfer_fullnames2(char *path_of_tree,FILE *out) {
539        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);         // 3 lines that should never be deleted
540        if (!cat_tree) return GB_get_error();
541        t2j_out = out;
542
543        int i;
544        for (i=0;i<cat_tree->nnodes;i++){
545                CAT_node *node = & cat_tree->nodes[i];
546                if (node->field_offsets[CAT_FIELD_FULL_NAME]) {
547                        node->user_data = cat_tree->data + node->field_offsets[CAT_FIELD_FULL_NAME];
548                        char *sep = strchr(node->user_data,' ');
549                        if (sep){
550                                while (*sep == ' ') sep++;
551                        }
552                        node->user_data = sep;
553                }
554                node->color = node->color_in;
555        }
556        return T2J_send_tree(0,0);
557}
558
559/***********************************************************************
560        Transfer inner node labels ...
561***********************************************************************/
562GB_ERROR T2J_transfer_group_names(char *path_of_tree,FILE *out) {
563        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);         // 3 lines that should never be deleted
564        if (!cat_tree) return GB_get_error();
565        t2j_out = out;
566
567        int i;
568        for (i=0;i<cat_tree->nnodes;i++){
569                CAT_node *node = & cat_tree->nodes[i];
570                if (node->field_offsets[CAT_FIELD_GROUP_NAME]) {
571                        node->user_data = cat_tree->data + node->field_offsets[CAT_FIELD_GROUP_NAME];
572                }
573               
574        }
575        return T2J_send_tree(0,0);
576}
577
578long    t2j_get_deepest_node_that_contains_all_selected(CAT_node_id nn, 
579                        char *selected_ids,long nselected, CAT_node_id *focusout){
580        CAT_node *node = & cat_tree->nodes[nn];
581        long sum = 0;
582        if (node->leftson > 0) {                // inner node
583                sum += t2j_get_deepest_node_that_contains_all_selected( node->leftson,
584                                selected_ids, nselected, focusout);
585                sum += t2j_get_deepest_node_that_contains_all_selected( node->rightson,
586                                selected_ids, nselected, focusout);
587        }else{
588                sum += selected_ids[nn];        // count the selected leafs
589        }
590        if (sum == nselected){                  // there is a hit !!
591                if (*focusout == 0) {           // and it is really the first one
592                        *focusout = nn;         // export it
593                }
594        }
595        return sum;
596}
597
598/***********************************************************************
599        Convert a selection into names ...
600***********************************************************************/
601/**     input path_of_tree      path of the tree.otb file
602        sel                     what is send from the java as a selection
603        varname                 a string that is prepended to the output
604        all_nodes               output = all nodes or just ranges
605
606        if all_nodes >0 then the programm calculates:
607        focusout                the internal id that contains all selected nodes
608        maxnodeout              the name of the inner node that contains all selected nodes
609        maxnodehits             relativ number of selected_nodes/tip beneath maxnodeout
610*/
611
612char *T2J_get_selection(char *path_of_tree, char *sel, const char *varname, int all_nodes,
613                        CAT_node_id *focusout, char **maxnodeout, double *maxnodehits){
614        if (!cat_tree)  cat_tree = load_CAT_tree(path_of_tree);
615        if (!cat_tree) return 0;
616        CAT_node_id *levelindex = t2j_mcreate_level_indexing();
617       
618        char *readp = sel;
619        int nselected = 0;
620        char *selected_ids = (char *)calloc(sizeof(char), cat_tree->nnodes);
621        void *memfile = GBS_stropen(1024);
622        int s,e;
623        int c;
624        int fac;
625        GBS_strcat(memfile,varname);
626        readp = sel;
627        c = *(readp++); 
628        int last = 0;
629        for (; c >='A' && c <='Z'; ){
630                fac = 1;s = last;
631                while ( c >='A' && c <='Z' ) {          // Read the start of the selection
632                        s += fac * (c-'A');
633                        fac *= 16;
634                        c = *(readp++);
635                }
636                fac = 1;e = s;
637                while ( c >='a' && c <='z' ) {          // End of the selection
638                        e += fac * (c-'a');
639                        fac *= 16;
640                        c = *(readp++);
641                }
642                if (e<=0) e=1;
643                if (s<0) s= 0;
644                if (e > cat_tree->nnodes) e = cat_tree->nnodes;
645                if (s >= cat_tree->nnodes) e = cat_tree->nnodes-1;
646                last = e;
647               
648                if (all_nodes) {
649                        for (;s<e;s++) {
650                                GBS_strcat(memfile,     cat_tree->data +
651                                        cat_tree->nodes[levelindex[s]].
652                                        field_offsets[CAT_FIELD_NAME]);
653                                nselected++;
654                                selected_ids[levelindex[s]] ++;
655                                GBS_chrcat(memfile,'#');
656                        }
657                }else{
658                        GBS_strcat(memfile,cat_tree->data + 
659                                cat_tree->nodes[levelindex[s]].field_offsets[CAT_FIELD_NAME]);
660                                        // thats one of my favourites statements
661                        GBS_chrcat(memfile,'#');
662                        GBS_strcat(memfile,cat_tree->data +
663                                cat_tree->nodes[levelindex[e-1]].field_offsets[CAT_FIELD_NAME]);
664                        GBS_chrcat(memfile,' ');
665                }
666        }
667        char *result = GBS_strclose(memfile,0);
668        if (focusout) {
669                *focusout = 0;
670                if (maxnodeout ) *maxnodeout = 0;
671                if (maxnodehits) *maxnodehits = 0.0;
672                if (nselected == 1) {
673                        t2j_get_deepest_node_that_contains_all_selected(
674                                                0,selected_ids,nselected,focusout);
675                                if (maxnodeout ) *maxnodeout = cat_tree->data + 
676                                        cat_tree->nodes[*focusout].
677                                        field_offsets[CAT_FIELD_NAME];
678                                if (maxnodehits) *maxnodehits = 1.0;
679                }else if (nselected) {
680                        t2j_get_deepest_node_that_contains_all_selected(
681                                                0,selected_ids,nselected,focusout);
682                        CAT_node_id nextuppderlabeldnode = *focusout;
683
684                        while ( nextuppderlabeldnode > 0 
685                                        && cat_tree->nodes[nextuppderlabeldnode].
686                                                field_offsets[CAT_FIELD_GROUP_NAME] == 0 ) {
687                                nextuppderlabeldnode = cat_tree->nodes[nextuppderlabeldnode].father;
688                        }
689                        if (nextuppderlabeldnode) {     // get the name of the node
690                                if (maxnodeout ) *maxnodeout = cat_tree->data + 
691                                        cat_tree->nodes[nextuppderlabeldnode].
692                                        field_offsets[CAT_FIELD_GROUP_NAME];
693                                if (maxnodehits) *maxnodehits = (double)nselected/
694                                        (double) cat_tree->nodes[nextuppderlabeldnode].nleafs;
695                        }
696                }
697        }
698        delete selected_ids;
699        return result;
700}
701
702/***********************************************************************
703        TEST TEST TEST ...
704***********************************************************************/
705#if 0 
706int main(int argc, char **argv) {
707        if (argc != 3) {
708                fprintf(stderr,"Syntax: %s treefilename datafile > outfile\n",argv[0]);
709                fprintf(stderr,"        %s -tree treefilename     > outfile\n",argv[0]);
710                fprintf(stderr,"        %s -bl treefilename     > outfile\n",argv[0]);
711                return -1;
712        }
713        char *error = 0;
714        if (!strcmp(argv[1],"-tree")){
715                error = T2J_send_bit_coded_tree(argv[2],stdout);
716        }else if (!strcmp (argv[1], "-bl")){
717                error = T2J_send_branch_lengths(argv[2],stdout);
718        }else{
719                T2J_transfer_struct *transfer = T2J_read_query_result_from_file(argv[2]);
720                if (!transfer){
721                        error = GB_get_error();
722                }
723                if (!error) error = T2J_transform(argv[1],0, transfer, 0, stdout);
724        }
725        if (error) {
726                fprintf(stderr,"%s\n",error);
727                return -1;
728        }
729        return 0;
730}
731#endif
Note: See TracBrowser for help on using the repository browser.