source: tags/ms_r16q3/EDIT4/EDB_root_bact.cxx

Last change on this file was 15288, checked in by westram, 8 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : EDB_root_bact.cxx                                 //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <ed4_extern.hxx>
12#include "ed4_class.hxx"
13
14#include <aw_msg.hxx>
15#include <arb_progress.h>
16#include <arbdbt.h>
17#include <arb_strbuf.h>
18#include <ad_config.h>
19
20void EDB_root_bact::calc_no_of_all(const char *string_to_scan, long *group, long *species) {
21    *group = 0;
22    *species = 0;
23
24    if (string_to_scan) {
25        long i = 0;
26        while (string_to_scan[i]) {
27            if (string_to_scan[i] == 1) {
28                if (string_to_scan[i+1] == 'L' || string_to_scan[i+1] == 'S') {
29                    (*species)++;
30                    i++;
31                }
32                else if (string_to_scan[i+1] == 'F' || string_to_scan[i+1] == 'G') {
33                    (*group)++;
34                    i++;
35                }
36            }
37            i++;
38        }
39    }
40}
41
42ED4_returncode EDB_root_bact::fill_data(ED4_multi_species_manager *multi_species_manager,
43                                        ED4_reference_terminals&   refterms,
44                                        char                      *str,
45                                        int                        group_depth,
46                                        ED4_datamode               datamode)
47{
48    GBDATA *gb_item = NULL;
49    switch (datamode) {
50        case ED4_D_EXTENDED: gb_item = GBT_find_SAI(GLOBAL_gb_main, str); break;
51        case ED4_D_SPECIES:  gb_item = GBT_find_species(GLOBAL_gb_main, str); break;
52    }
53
54    if (!gb_item) { // didn't find this species/SAI
55        not_found_counter++;
56        if (not_found_counter <= MAX_SHOWN_MISSING_SPECIES) {
57            char dummy[150];
58            sprintf(dummy, "%zu. %s\n", not_found_counter, str);
59            e4_assert(not_found_message);
60            GBS_strcat(not_found_message, dummy);
61        }
62        return ED4_R_BREAK;
63    }
64
65    // check whether sequence has data in desired alignment
66    bool has_alignment = 0 != GB_entry(gb_item, ED4_ROOT->alignment_name);
67    if (!has_alignment) {
68        if (datamode == ED4_D_SPECIES) { // only warn about species w/o data (SAIs are skipped silently)
69            not_found_counter++;
70            if (not_found_counter <= MAX_SHOWN_MISSING_SPECIES) {
71                char dummy[150];
72                sprintf(dummy, "%zu. %s (no data in alignment)\n", not_found_counter, str);
73                GBS_strcat(not_found_message, dummy);
74            }
75        }
76        return ED4_R_BREAK;
77    }
78
79    ED4_species_type spec_type = (datamode == ED4_D_EXTENDED) ? ED4_SP_SAI : ED4_SP_SPECIES;
80
81
82    {
83        char namebuffer[NAME_BUFFERSIZE];
84        int count_two = 0;
85
86        sprintf(namebuffer, "Species_Manager.%ld.%d", ED4_counter, count_two);
87        ED4_species_manager *species_manager = new ED4_species_manager(spec_type, namebuffer, 0, 0, multi_species_manager);
88
89        species_manager->set_property(PROP_MOVABLE);
90        if (spec_type == ED4_SP_SAI) {
91            ED4_abstract_group_manager *group_man = species_manager->get_parent(ED4_level(LEV_GROUP|LEV_ROOTGROUP))->to_abstract_group_manager();
92            group_man->table().ignore_me(); // ignore SAI tables (does not work - instead ignore SAIs when calculating consensus)
93        }
94        species_manager->set_species_pointer(gb_item);
95        multi_species_manager->append_member(species_manager);
96
97        sprintf(namebuffer, "MultiName_Manager.%ld.%d", ED4_counter, count_two);
98        ED4_multi_name_manager *multi_name_manager = new ED4_multi_name_manager(namebuffer, 0, 0, species_manager);
99        species_manager->append_member(multi_name_manager);
100
101        sprintf(namebuffer, "MultiSeq_Manager.%ld.%d", ED4_counter, count_two++);
102        ED4_multi_sequence_manager *multi_sequence_manager = new ED4_multi_sequence_manager(namebuffer, 0, 0, species_manager);
103        species_manager->append_member(multi_sequence_manager);
104
105        sprintf(namebuffer, "Name_Manager%ld.%d", ED4_counter, count_two++);
106        ED4_name_manager *name_manager = new ED4_name_manager(namebuffer, 0, 0, multi_name_manager);
107        name_manager->set_property(PROP_MOVABLE); // only Speciesname should be movable
108        multi_name_manager->append_member(name_manager);
109
110        {
111            sprintf(namebuffer, "Species_Name_Term%ld.%d", ED4_counter, count_two++);
112            ED4_species_name_terminal *species_name_terminal = new ED4_species_name_terminal(namebuffer, MAXNAME_WIDTH-(group_depth*BRACKET_WIDTH), TERMINAL_HEIGHT, name_manager);
113            species_name_terminal->set_property((ED4_properties) (PROP_SELECTABLE | PROP_DRAGABLE | PROP_IS_HANDLE));
114            species_name_terminal->set_links(NULL, refterms.sequence());
115            species_name_terminal->set_species_pointer(GB_entry(gb_item, "name"));
116            name_manager->append_member(species_name_terminal);
117        }
118
119        {
120            sprintf(namebuffer, "Flag_Term%ld.%d", ED4_counter, count_two++);
121            ED4_flag_terminal *flag_terminal = new ED4_flag_terminal(namebuffer, FLAG_WIDTH, TERMINAL_HEIGHT, name_manager);
122            flag_terminal->set_links(NULL, refterms.sequence());
123            name_manager->append_member(flag_terminal);
124        }
125
126        GBDATA *gb_ali_xxx = GB_entry(gb_item, ED4_ROOT->alignment_name);
127        if (gb_ali_xxx) {
128            search_sequence_data_rek(multi_sequence_manager, refterms, gb_ali_xxx, count_two, &max_seq_terminal_length, datamode == ED4_D_EXTENDED);
129        }
130    }
131
132    return ED4_R_OK;
133}
134
135ED4_returncode EDB_root_bact::search_sequence_data_rek(ED4_multi_sequence_manager *multi_sequence_manager,
136                                                       ED4_reference_terminals&    refterms,
137                                                       GBDATA                     *gb_ali_xxx, // alignment-container (or any subcontainer of)
138                                                       int                         count_too,
139                                                       ED4_index                  *max_sequence_terminal_length,
140                                                       bool                        isSAI)
141{
142    char       namebuffer[NAME_BUFFERSIZE];
143    AW_device *device = ED4_ROOT->first_window->get_device();
144
145    e4_assert(gb_ali_xxx);
146
147    for (GBDATA *gb_ali_child = GB_child(gb_ali_xxx); gb_ali_child; gb_ali_child = GB_nextChild(gb_ali_child)) {
148        GB_TYPES type = GB_read_type(gb_ali_child);
149
150        if (type == GB_INTS || type == GB_FLOATS) {
151            continue;
152        }
153
154        if (type == GB_DB) {  // we have to unpack container
155            search_sequence_data_rek(multi_sequence_manager, refterms, gb_ali_child, count_too, max_sequence_terminal_length, isSAI);
156        }
157        else { // otherwise we enter the data
158            char *key_string = GB_read_key(gb_ali_child);
159            if (key_string[0] != '_') { // don't show sequences starting with an underscore
160                sprintf(namebuffer, "Sequence_Manager.%ld.%d", ED4_counter, count_too++);
161                ED4_sequence_manager *seq_manager = new ED4_sequence_manager(namebuffer, 0, 0, multi_sequence_manager);
162                seq_manager->set_property(PROP_MOVABLE);
163                multi_sequence_manager->append_member(seq_manager);
164
165                {
166                    ED4_sequence_info_terminal *sequence_info_terminal = new ED4_sequence_info_terminal(key_string, SEQUENCE_INFO_WIDTH, TERMINAL_HEIGHT, seq_manager);
167                    sequence_info_terminal->set_property((ED4_properties) (PROP_SELECTABLE | PROP_DRAGABLE | PROP_IS_HANDLE));
168                    sequence_info_terminal->set_both_links(refterms.sequence_info());
169                    sequence_info_terminal->set_species_pointer(gb_ali_child);
170                    seq_manager->append_member(sequence_info_terminal);
171                }
172
173                ED4_text_terminal *text_terminal = 0;
174
175                bool is_data    = false;
176                bool is_data2   = false;
177                bool is_bits    = false;
178                bool is_quality = false;
179
180                if      (strcmp(key_string, "data")    == 0) is_data    = true; // SAI or species
181                else if (strcmp(key_string, "data2")   == 0) is_data2   = true; // used by SAIs with two entries (e.g. first and second digit of 2-digit-numbers)
182                else if (strcmp(key_string, "bits")    == 0) is_bits    = true; // used by binary SAIs (e.g. MARKERLINE)
183                else if (strcmp(key_string, "quality") == 0) is_quality = true; // used by "quality" entry written by chimera check; see ../STAT/ST_quality.cxx@chimera_check_quality_string
184
185                bool is_aligned = is_data || is_data2 || is_bits || is_quality;
186
187                if (is_aligned) {
188                    bool shall_display_secinfo = is_data;
189
190                    if (isSAI) {
191                        GBDATA *gb_sai        = GB_get_grandfather(gb_ali_child);
192                        GBDATA *gb_disp_sec   = GB_searchOrCreate_int(gb_sai, "showsec", 0);
193                        shall_display_secinfo = GB_read_int(gb_disp_sec);
194                    }
195
196                    sprintf(namebuffer, "Sequence_Term%ld.%d", ED4_counter, count_too++);
197                    ED4_sequence_terminal *seq_term = new ED4_sequence_terminal(namebuffer, 0, TERMINAL_HEIGHT, seq_manager, shall_display_secinfo);
198                    seq_term->species_name          = seq_term->get_name_of_species();
199
200                    if (is_data) seq_term->set_property(PROP_CONSENSUS_RELEVANT);
201                    seq_term->set_property(PROP_ALIGNMENT_DATA);
202
203                    text_terminal = seq_term;
204                }
205                else {
206                    sprintf(namebuffer, "PureText_Term%ld.%d", ED4_counter, count_too++);
207                    text_terminal = new ED4_pure_text_terminal(namebuffer, 0, TERMINAL_HEIGHT, seq_manager);
208                }
209
210                text_terminal->set_property(PROP_CURSOR_ALLOWED);
211                text_terminal->set_both_links(refterms.sequence());
212                seq_manager->append_member(text_terminal);
213#if defined(DEBUG)
214                // ensure only 1 terminal is consensus-relevant!
215                if (is_data) {
216                    seq_manager->get_consensus_relevant_terminal(); // does an error otherwise!
217                }
218#endif // DEBUG
219                text_terminal->set_species_pointer(gb_ali_child);
220
221                long string_length;
222                if (gb_ali_child) {
223                    string_length = GB_read_count(gb_ali_child);
224                }
225                else {
226                    string_length = 100;
227                }
228
229                int pixel_length = device->get_string_size(ED4_G_SEQUENCES, NULL, string_length) + 100; // @@@ "+ 100" looks like a hack
230
231                *max_sequence_terminal_length = std::max(*max_sequence_terminal_length, long(pixel_length));
232                text_terminal->extension.size[WIDTH] = pixel_length;
233
234                if (MAXSEQUENCECHARACTERLENGTH < string_length) {
235                    MAXSEQUENCECHARACTERLENGTH = string_length;
236                    refterms.sequence()->extension.size[WIDTH] = pixel_length;
237                }
238
239                if (!ED4_ROOT->scroll_links.link_for_hor_slider) {
240                    ED4_ROOT->scroll_links.link_for_hor_slider = text_terminal;
241                }
242                else if (*max_sequence_terminal_length > ED4_ROOT->scroll_links.link_for_hor_slider->extension.size[WIDTH]) {
243                    ED4_ROOT->scroll_links.link_for_hor_slider = text_terminal;
244                }
245            }
246            free(key_string);
247        }
248    }
249
250    return ED4_R_OK;
251}
252
253
254char* EDB_root_bact::make_string()
255{
256    const char *sep_name     = "\1"; // Trennzeichen
257    char*       configstring = new char[500];
258
259    strcpy(configstring, sep_name);
260
261    strcat(configstring, "FGruppe1lang");
262    strcat(configstring, sep_name);
263    strcat(configstring, "SHELIX_PAIRS");
264    strcat(configstring, sep_name);
265    strcat(configstring, "SHELIX_LINE");
266    strcat(configstring, sep_name);
267    strcat(configstring, "E");
268    strcat(configstring, sep_name);
269    strcat(configstring, "GFltDorot");  // Speciesmark L
270    strcat(configstring, sep_name);
271    strcat(configstring, "LCasElega");
272    strcat(configstring, sep_name);
273    strcat(configstring, "E");
274    strcat(configstring, sep_name);
275    strcat(configstring, "LBaeFrag3");
276    strcat(configstring, sep_name);
277    strcat(configstring, "LFlaFerr2");
278    strcat(configstring, sep_name);
279    strcat(configstring, "LCytLyti3");
280    strcat(configstring, "\0");
281
282    return configstring;
283}
284
285char* EDB_root_bact::make_top_bot_string()          // is only called when started manually
286{
287    char* configstring;
288    configstring = new char[400];
289    sprintf(configstring, "%cFSAI's%cSHELIX_PAIRS%cSHELIX_LINE%cSALI_ERR%cSALI_CON%cSALI_INT%cSALI_BIND%cSantibiot%cSmodnuc%cSelong%cStRNA%cSALI_BOR%cSALI_PRE_I%cSALI_PRE%cSALI_INSERTS%cSinseuca2%cSregaps%cSallr5%cSbacr5%cSarcr5%cSeucr5%cSgplr5%cSinsEuca%cSprimer1%cSprimer2%cSbetar5%cSprimer3%cE", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
290
291    strcat(configstring, "\0");
292
293    return configstring;
294}
295
296
297ED4_returncode  EDB_root_bact::fill_species(ED4_multi_species_manager *multi_species_manager,
298                                            ED4_reference_terminals&   refterms,
299                                            const char                *str,
300                                            int                       *index,
301                                            int                        group_depth,
302                                            arb_progress              *progress)
303{
304    const int MAXNAMELEN = 1024;
305
306    bool         expect_separator = true;
307    ED4_datamode datamode         = ED4_D_SPECIES;
308    ED4_returncode retCode        = ED4_R_OK;
309
310    char *name = ARB_calloc<char>(MAXNAMELEN);
311    int   npos = 0;
312
313    do {
314        if (expect_separator) {
315            if (str[(*index)+1] == 'L') {
316                datamode = ED4_D_SPECIES;
317            }
318            else if (str[(*index)+1] == 'S') {
319                datamode = ED4_D_EXTENDED;
320            }
321            else {
322                const char *entry = str+*index+1;
323                char        tag   = entry[0];
324                const char *sep   = strchr(entry, 1);
325
326                if (sep) {
327                    int   len     = sep-entry+1;
328                    char *content = ARB_strndup(entry+1, len);
329                    char *message = GBS_global_string_copy("Unknown or misplaced tag-id '%c' (with content '%s'). Error in configuration-data!\nTrying to continue..", tag, content);
330
331                    fprintf(stderr, "ARB_EDIT4: %s\n", message);
332                    aw_message(message);
333
334                    free(message);
335                    free(content);
336                    retCode = ED4_R_WARNING;
337
338                    (*index) += sep-entry+1; // set index to next separator
339                    continue;
340                }
341                else {
342                    fprintf(stderr, "Error reading configuration: Unexpected end of data (at '%s')\n", str+*index);
343
344                    e4_assert(0);
345                    retCode = ED4_R_ERROR;
346                    break;
347                }
348                e4_assert(0); // never reached!
349            }
350
351            (*index) += 2;
352        }
353
354        if (str[*index] != 1) {
355            name[npos++] = str[*index];
356            expect_separator = false;
357            (*index)++;
358        }
359
360        if (str[*index] == 1 || str[*index] == '\0') {
361            name[npos] = '\0'; // speciesname-generation finished
362            npos = 0;
363
364            if (progress) {
365                progress->inc();
366                if (progress->aborted()) ED4_exit();
367            }
368
369            fill_data(multi_species_manager, refterms, name, group_depth, datamode);
370
371            ED4_counter++;
372            expect_separator = true;
373        }
374    }
375    while (!((str[(*index)] == 1) && (str[(*index)+1] == 'G' || str[(*index)+1]=='E' || str[(*index)+1]=='F')) && (str[*index] != '\0'));
376
377    free(name);
378
379    return retCode;
380}
381
382void EDB_root_bact::scan_string(ED4_multi_species_manager *parent,
383                                ED4_reference_terminals&   refterms,
384                                const char                *str,
385                                int                       *index,
386                                arb_progress&              progress)
387{
388    static int group_depth = 0;
389
390    while (str[(*index)] != '\0' && str[(*index)+1] != 'E') { // E =
391        if (str[(*index)+1] == 'L' || str[(*index)+1] == 'S') {   // L = species, S = SAI
392            fill_species(parent, refterms, str, index, group_depth, &progress);
393            ED4_counter++; // counter is only needed to generate ids
394        }
395
396        if (str[(*index)] && (str[(*index)+1] == 'G' || str[(*index)+1] == 'F')) { // Group or folded group
397            group_depth++;
398            bool is_folded = str[(*index)+1]=='F';
399
400            char groupname[GB_GROUP_NAME_MAX];
401            {
402                ED4_index gpos = 0;
403                for (*index += 2, gpos = 0; str[*index] != 1; (*index)++) {  // Jump over 'G' and Blank to get Groupname
404                    groupname[gpos++] = str[*index];
405                }
406                groupname[gpos] = '\0';
407            }
408
409            ED4_multi_species_manager *multi_species_manager;
410            ED4_build_group_manager_start(parent, groupname, group_depth, is_folded, refterms, multi_species_manager);
411
412            ED4_counter++;
413            scan_string(multi_species_manager, refterms, str, index, progress);
414
415            ED4_build_group_manager_end(multi_species_manager);
416
417            if (is_folded) multi_species_manager->hide_children();
418        }
419    }
420
421    if (str[(*index)] && str[(*index)+1] == 'E') {
422        (*index)+=2;
423        group_depth--;
424    }
425}
426
427void EDB_root_bact::save_current_config(char *confname) { // and save it in database
428    GB_ERROR   error;
429    GBT_config cfg(GLOBAL_gb_main, confname, error);
430    error = NULL; // ignore not-found error
431
432    int                 counter        = 0;
433    ED4_device_manager *device_manager = ED4_ROOT->get_device_manager();
434
435    for (int i=0; i<device_manager->members(); i++) {
436        ED4_base *area = device_manager->member(i);
437        if (area->is_area_manager()) {
438            GBS_strstruct area_config(10000);
439            area->generate_configuration_string(area_config);
440            cfg.set_definition(counter++, area_config.release());
441        }
442    }
443
444    // add/update comment
445    {
446        char *newComment = GBS_log_dated_action_to(cfg.get_comment(), "saved from ARB_EDIT4");
447        cfg.set_comment(newComment);
448        free(newComment);
449    }
450
451    error = cfg.save(GLOBAL_gb_main, confname, true);
452    aw_message_if(error);
453}
454
Note: See TracBrowser for help on using the repository browser.