source: branches/port5/TOOLS/arb_read_tree.cxx

Last change on this file was 6024, checked in by westram, 15 years ago
  • renamed tree IO functions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1#include <TreeRead.h>
2#include <time.h>
3
4// add_bootstrap interprets the length of the branches as bootstrap value
5// (this is needed by Phylip DNAPARS/PROTPARS with bootstrapping)
6//
7// 'hundred' specifies which value represents 100%
8
9void add_bootstrap(GBT_TREE *node, double hundred) {
10    if (node->is_leaf) {
11        freeset(node->remark_branch, 0);
12        return;
13    }
14
15    node->leftlen  /= hundred;
16    node->rightlen /= hundred;
17
18    double left_bs  = node->leftlen  * 100.0 + 0.5;
19    double right_bs = node->rightlen * 100.0 + 0.5;
20
21#if defined(DEBUG) && 0
22    fprintf(stderr, "node->leftlen  = %f left_bs  = %f\n", node->leftlen, left_bs);
23    fprintf(stderr, "node->rightlen = %f right_bs = %f\n", node->rightlen, right_bs);
24#endif // DEBUG
25
26    node->leftson->remark_branch  = GBS_global_string_copy("%2.0f%%", left_bs);
27    node->rightson->remark_branch = GBS_global_string_copy("%2.0f%%", right_bs);
28
29    node->leftlen  = 0.1; // reset branchlengths
30    node->rightlen = 0.1;
31
32    add_bootstrap(node->leftson, hundred);
33    add_bootstrap(node->rightson, hundred);
34}
35
36ATTRIBUTED(__ATTR__NORETURN, static void abort_with_usage(GBDATA *gb_main, const char *error)) {
37    printf("Usage: arb_read_tree [-scale factor] [-consense #ofTrees] tree_name treefile [comment] [-commentFromFile file]\n");
38    if (error) {
39        printf("Error: %s\n", error);
40        GBT_message(gb_main, GBS_global_string("Error running arb_read_tree (%s)", error));
41    }
42    exit(-1);
43}
44
45int main(int argc,char **argv)
46{
47    GBDATA *gb_main = GB_open(":","r");
48    if (!gb_main){
49        printf("arb_read_tree: Error: you have to start an arbdb server first\n");
50        return -1;
51    }
52
53#define SHIFT_ARGS(off) do { argc -= off; argv += off; } while(0)
54
55    SHIFT_ARGS(1);              // position onto first argument
56
57    bool   scale        = false;
58    double scale_factor = 0.0;
59
60    if (argc>0 && strcmp("-scale",argv[0]) == 0) {
61        scale = true;
62        if (argc<2) abort_with_usage(gb_main, "-scale expects a 2nd argument (scale factor)");
63        scale_factor = atof(argv[1]);
64        SHIFT_ARGS(2);
65    }
66
67    bool consense         = false;
68    int  calculated_trees = 0;
69
70    if (argc>0 && strcmp("-consense",argv[0]) == 0) {
71        consense = true;
72        if (argc<2) abort_with_usage(gb_main, "-consense expects a 2nd argument (number of trees)");
73
74        calculated_trees = atoi(argv[1]);
75        if (calculated_trees < 1) {
76            abort_with_usage(gb_main, GBS_global_string("Illegal # of trees (%i) for -consense", calculated_trees));
77        }
78
79        SHIFT_ARGS(2);
80    }
81
82    if (!argc) abort_with_usage(gb_main, "Missing argument 'tree_name'");
83    const char *tree_name = argv[0];
84    SHIFT_ARGS(1);
85
86    if (!argc) abort_with_usage(gb_main, "Missing argument 'treefile'");
87    const char *filename = argv[0];
88    SHIFT_ARGS(1);
89
90    const char *comment = 0;
91    if (argc>0) {
92        comment = argv[0];
93        SHIFT_ARGS(1);
94    }
95
96    const char *commentFile = 0;
97    if (argc>0 && strcmp("-commentFromFile", argv[0]) == 0) {
98        if (argc<2) abort_with_usage(gb_main, "-commentFromFile expects a 2nd argument (file containing comment)");
99        commentFile = argv[1];
100        SHIFT_ARGS(2);
101    }
102
103    // end of argument parsing!
104    if (argc>0) abort_with_usage(gb_main, GBS_global_string("unexpected argument(s): %s ..", argv[0]));
105
106    // --------------------------------------------------------------------------------
107
108    char *comment_from_file = 0;
109    if (commentFile) {
110        comment_from_file = GB_read_file(commentFile);
111        if (!comment_from_file) {
112            comment_from_file = GBS_global_string_copy("Error reading from comment-file '%s':\n%s", commentFile, GB_await_error());
113        }
114    }
115
116    char *comment_from_treefile = 0;
117    GBT_message(gb_main, GBS_global_string("Reading tree from '%s' ..", filename));
118
119    GB_ERROR  error = 0;
120    GBT_TREE *tree;
121    {
122        char *scaleWarning = 0;
123
124        tree = TREE_load(filename, sizeof(GBT_TREE), &comment_from_treefile, (consense||scale) ? 0 : 1, &scaleWarning);
125        if (!tree) {
126            error = GB_await_error();
127        }
128        else {
129            if (scaleWarning) {
130                GBT_message(gb_main, scaleWarning);
131                free(scaleWarning);
132            }
133        }
134    }
135
136    if (!error) {
137        if (scale) {
138            GBT_message(gb_main, GBS_global_string("Scaling branch lengths by factor %f.", scale_factor));
139            TREE_scale(tree, scale_factor, 1.0);
140        }
141
142        if (consense) {
143            if (calculated_trees < 1) {
144                error = "Minimum for -consense is 1";
145            }
146            else {
147                GBT_message(gb_main, GBS_global_string("Reinterpreting branch lengths as consense values (%i trees).", calculated_trees));
148                add_bootstrap(tree, calculated_trees);
149            }
150        }
151    }
152
153    if (!error) {
154        error = GB_begin_transaction(gb_main);
155       
156        if (!error && tree->is_leaf) error = "Cannot load tree (need at least 2 leafs)";
157        if (!error) error                  = GBT_write_tree(gb_main,0,tree_name,tree);
158
159        if (!error) {
160            // write tree comment:
161            const char *datestring;
162            {
163                time_t date;
164                if (time(&date) == -1) datestring = "<Error calculating time>";
165                else datestring = ctime(&date);
166            }
167
168            char *load_info = GBS_global_string_copy("Tree loaded from '%s' on %s", filename, datestring);
169
170#define COMMENT_SOURCES 4
171            const char *comments[COMMENT_SOURCES] = {
172                comment,
173                comment_from_file,
174                comment_from_treefile,
175                load_info,
176            };
177
178            GBS_strstruct *buf   = GBS_stropen(5000);
179            bool           empty = true;
180
181            for (int c = 0; c<COMMENT_SOURCES; c++) {
182                if (comments[c]) {
183                    if (!empty) GBS_chrcat(buf, '\n');
184                    GBS_strcat(buf, comments[c]);
185                    empty = false;
186                }
187            }
188
189            char *cmt = GBS_strclose(buf);
190
191            error = GBT_write_tree_rem(gb_main, tree_name, cmt);
192
193            free(cmt);
194            free(load_info);
195        }
196
197        error = GB_end_transaction(gb_main, error);
198    }
199
200    if (error) GBT_message(gb_main, error);
201    else GBT_message(gb_main, GBS_global_string("Tree %s read into the database", tree_name));
202   
203    GB_close(gb_main);
204
205    free(comment_from_file);
206    free(comment_from_treefile);
207
208    return error ? EXIT_FAILURE : EXIT_SUCCESS;
209}
Note: See TracBrowser for help on using the repository browser.