source: branches/stable/CORE/arb_progress.cxx

Last change on this file was 11401, checked in by westram, 6 years ago
  • reintegrates 'tree' into 'trunk':
    • consensus trees:
      • support for merging partial trees ("worked" before, but results were crap; implements #65)
      • generated trees are automatically re-rooted and -ordered
      • always list source trees in consensus-tree-comment; show info about partial trees
      • fixed progress bar
    • made GBT_TREE a base class of other tree classes (implements #31)
    • save tree properties in properties (not in DB)
    • new functions 'Remove zombies/marked from ALL trees'
    • tree load/save: layout fixes
    • unit tests
      • added tests for basic tree modifications (PARSIMONY)
    • performance:
      • compute_tree updates tree information in one traversal
      • tree generators are now capable to generate any type of tree (w/o needing to copy it once)
    • bugfixes:
      • NNI (of marked species) was also always performed for colored species
      • centered beautify-order is stable now
      • improved 'search optimal root'
  • adds:
File size: 10.2 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : arb_progress.cxx                                   //
4//   Purpose   :                                                    //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in November 2010   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#include <arb_progress.h>
13#include <arb_handlers.h>
14#include <arb_msg.h>
15#include <algorithm>
16
17// ----------------
18//      counter
19
20struct null_counter: public arb_progress_counter {
21    null_counter(arb_parent_progress *progress_) : arb_progress_counter(progress_) {}
22
23    void inc() OVERRIDE {}
24    void implicit_inc() OVERRIDE {}
25    void done() OVERRIDE {}
26    void restart(int) OVERRIDE {}
27    void force_update() OVERRIDE {}
28    void auto_subtitles(const char *) OVERRIDE {}
29    bool has_auto_subtitles() OVERRIDE { return false; }
30    void child_updates_gauge(double ) OVERRIDE {
31        arb_assert(0); // wont
32    }
33
34#if defined(DUMP_PROGRESS)
35    void dump() OVERRIDE {
36        fprintf(stderr, "null_counter\n");
37    }
38#endif
39
40    arb_progress_counter* clone(arb_parent_progress *parent_, int ) const OVERRIDE { return new null_counter(parent_); }
41};
42
43struct no_counter : public null_counter {
44    no_counter(arb_parent_progress *progress_) : null_counter(progress_) {}
45    void inc() OVERRIDE {
46        arb_assert(0); // this is no_counter - so explicit inc() is prohibited!
47    }
48    void child_updates_gauge(double gauge) OVERRIDE { progress->update_gauge(gauge); }
49   
50#if defined(DUMP_PROGRESS)
51    void dump() OVERRIDE {
52        fprintf(stderr, "no_counter (=wrapper)\n");
53    }
54#endif
55};
56
57class concrete_counter: public arb_progress_counter { // derived from a Noncopyable
58    int     explicit_counter; // incremented by calls to inc() etc.
59    int     implicit_counter; // incremented by child_done()
60    int     maxcount;         // == 0 -> does not really count (just a wrapper for child progresses)
61    double  autoUpdateEvery;
62    double  nextAutoUpdate;
63    char   *auto_subtitle_prefix;
64    int     last_auto_counter;
65
66    int dispositive_counter() const { return std::max(implicit_counter, explicit_counter); }
67
68    void init(int overallCount) {
69        arb_assert(overallCount>0);
70
71        implicit_counter  = 0;
72        explicit_counter  = 0;
73        maxcount          = overallCount;
74        autoUpdateEvery   = overallCount/500.0; // update status approx. 500 times
75        nextAutoUpdate    = 0;
76    }
77
78    bool refresh_if_needed(double my_counter) {
79        if (my_counter<nextAutoUpdate) return false;
80        progress->update_gauge(my_counter/maxcount);
81        if (auto_subtitle_prefix) {
82            int count = int(my_counter+1);
83            if (count>last_auto_counter && count <= maxcount) {
84                const char *autosub = GBS_global_string("%s #%i/%i", auto_subtitle_prefix, count, maxcount);
85                progress->set_text(LEVEL_SUBTITLE, autosub);
86                last_auto_counter   = count;
87            }
88        }
89        nextAutoUpdate += autoUpdateEvery;
90        return true;
91    }
92    void update_display_if_needed() {
93        int dcount = dispositive_counter();
94        arb_assert(dcount <= maxcount);
95        refresh_if_needed(dcount);
96    }
97
98    void force_update() OVERRIDE {
99        int oldNext    = nextAutoUpdate;;
100        nextAutoUpdate = 0;
101        update_display_if_needed();
102        nextAutoUpdate = oldNext;
103    }
104
105public:
106    concrete_counter(arb_parent_progress *parent, int overall_count)
107        : arb_progress_counter(parent),
108          auto_subtitle_prefix(NULL),
109          last_auto_counter(0)
110    {
111        arb_assert(overall_count>0);
112        init(overall_count);
113    }
114    ~concrete_counter() OVERRIDE {
115        free(auto_subtitle_prefix);
116#if defined(TEST_COUNTERS)
117        if (!progress->accept_invalid_counters) {
118            arb_assert(implicit_counter || explicit_counter); // progress was never incremented
119           
120            arb_assert(implicit_counter <= maxcount); // overflow
121            arb_assert(explicit_counter <= maxcount); // overflow
122
123            arb_assert(dispositive_counter() == maxcount); // progress did not finish
124        }
125#endif
126    }
127
128#if defined(DUMP_PROGRESS)
129    void dump() OVERRIDE {
130        fprintf(stderr,
131                "concrete_counter: explicit=%i, implicit=%i, maxcount=%i\n", 
132                explicit_counter, implicit_counter, maxcount);
133    }
134#endif
135
136    void auto_subtitles(const char *prefix) OVERRIDE {
137        arb_assert(!auto_subtitle_prefix);
138        freedup(auto_subtitle_prefix, prefix);
139        force_update();
140    }
141    bool has_auto_subtitles() OVERRIDE { return auto_subtitle_prefix; }
142
143    void inc()          OVERRIDE { explicit_counter += 1; update_display_if_needed(); }
144    void implicit_inc() OVERRIDE { implicit_counter += 1; update_display_if_needed(); }
145   
146    void done() OVERRIDE {
147        implicit_counter = explicit_counter = maxcount;
148        force_update();
149    }
150
151    void restart(int overallCount) OVERRIDE {
152        init(overallCount);
153        force_update();
154    }
155
156    arb_progress_counter* clone(arb_parent_progress *parent, int overall_count) const OVERRIDE {
157        return new concrete_counter(parent, overall_count);
158    }
159    void child_updates_gauge(double child_gauge) OVERRIDE {
160        refresh_if_needed(dispositive_counter()+child_gauge);
161    }
162};
163
164// -----------------
165//      progress
166
167
168class child_progress : public arb_parent_progress { // derived from a Noncopyable
169    arb_parent_progress *parent;
170
171public:
172    child_progress(arb_parent_progress *parent_, const char *title, int overall_count)
173        : arb_parent_progress(overall_count
174                              ? (arb_progress_counter*)new concrete_counter(this, overall_count)
175                              : (arb_progress_counter*)new no_counter(this),
176                              title),
177          parent(parent_)
178    {
179        set_text(LEVEL_TITLE, title);
180#if defined(DUMP_PROGRESS)
181        freedup(name, GBS_global_string("child: %s", title));
182#endif
183    }
184    ~child_progress() OVERRIDE {
185        parent->child_terminated();
186    }
187
188    SmartPtr<arb_parent_progress> create_child_progress(const char *title, int overall_count) OVERRIDE {
189        return new child_progress(this, title, overall_count);
190    }
191
192#if defined(DUMP_PROGRESS)
193    void dump() OVERRIDE {
194        arb_parent_progress::dump();
195        fprintf(stderr, "is child of\n");
196        parent->dump();
197    }
198#endif
199
200    bool aborted() const OVERRIDE { return parent->aborted(); }
201    void set_text(int level, const char *text) OVERRIDE { parent->child_sets_text(level+has_title-1, text); }
202   
203    void update_gauge(double gauge) OVERRIDE { parent->child_updates_gauge(gauge); }
204};
205
206class initial_progress: public arb_parent_progress {
207    bool user_abort;
208   
209public:
210    initial_progress(const char *title, arb_progress_counter *counter_)
211        : arb_parent_progress(counter_, title),
212          user_abort(false)
213    {
214        if (!title) title = "..."; // use fake title (arb_parent_progress got no title, so it will be replaced by child title)
215        impl->openstatus(title);
216#if defined(DUMP_PROGRESS)
217        freedup(name, GBS_global_string("initial: %s", title));
218#endif
219    }
220    ~initial_progress() OVERRIDE {
221        update_gauge(1.0); // due to numeric issues it often only counts up to 99.999%
222        impl->closestatus();
223    }
224
225    SmartPtr<arb_parent_progress> create_child_progress(const char *title, int overall_count) OVERRIDE {
226        return new child_progress(this, title, overall_count);
227    }
228
229    bool aborted() const OVERRIDE { return user_abort; }
230    void set_text(int level, const char *text) OVERRIDE {
231        if (!text) return;
232        switch (level+has_title-1) {
233            case LEVEL_TITLE: impl->set_title(text); break;
234            case LEVEL_SUBTITLE: impl->set_subtitle(text); break;
235        }
236    }
237
238    void update_gauge(double gauge) OVERRIDE { user_abort = impl->set_gauge(gauge); }
239};
240
241struct initial_wrapping_progress: public initial_progress {
242    initial_wrapping_progress(const char *title)
243        : initial_progress(title, new no_counter(this)) {}
244};
245struct initial_counting_progress : public initial_progress {
246    initial_counting_progress(const char *title, int overall_count)
247        : initial_progress(title, new concrete_counter(this, overall_count)) {}
248};
249
250struct null_progress: public arb_parent_progress {
251    null_progress(arb_progress_counter *counter_)
252        : arb_parent_progress(counter_, false)
253    {
254#if defined(DUMP_PROGRESS)
255        freedup(name, "null_progress");
256#endif
257    }
258
259    SmartPtr<arb_parent_progress> create_child_progress(const char*, int overall_count) OVERRIDE {
260        return new null_progress(clone_counter(overall_count));
261    }
262    bool aborted() const OVERRIDE { return false; }
263    void set_text(int,const char*) OVERRIDE {}
264    void update_gauge(double) OVERRIDE {}
265};
266
267// -------------------------
268//      progress factory
269
270arb_parent_progress       *arb_parent_progress::recent = NULL;
271arb_status_implementation *arb_parent_progress::impl   = NULL; // defines implementation to display status
272
273SmartPtr<arb_parent_progress> arb_parent_progress::create(const char *title, int overall_count) {
274    if (recent) {
275        return recent->create_child_progress(title, overall_count);
276    }
277
278    impl = &active_arb_handlers->status;
279
280    if (overall_count == 0) return new initial_wrapping_progress(title);
281    return new initial_counting_progress(title, overall_count);
282
283}
284
285SmartPtr<arb_parent_progress> arb_parent_progress::create_suppressor() {
286    return new null_progress(new null_counter(NULL));
287}
288
289// --------------------------
290//      progress dumpers
291
292#if defined(DUMP_PROGRESS)
293
294// not inlined in header (otherwise they are missing while debugging)
295
296void arb_parent_progress::dump() {
297    fprintf(stderr, "progress '%s'\n", name);
298    fprintf(stderr, "counter: ");
299    counter->dump();
300}
301void arb_progress::dump() {
302    fprintf(stderr, "--------------------\n");
303    used->dump();
304}
305
306#endif
307
Note: See TracBrowser for help on using the repository browser.