source: trunk/NTREE/NT_trackAliChanges.cxx @ 6280

Last change on this file since 6280 was 6280, checked in by westram, 15 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_trackAliChanges.cxx                            //
4//   Purpose   : Track alignment and sequences changes             //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in June 2007      //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#include "NT_trackAliChanges.h"
13
14#include <awt_sel_boxes.hxx>
15#include <aw_window.hxx>
16#include <ctime>
17
18extern GBDATA *GLOBAL_gb_main;
19
20#define AWAR_TRACK_BASE     "track/"
21#define AWAR_TRACK_ALI      AWAR_TRACK_BASE "ali"
22#define AWAR_TRACK_INITIALS AWAR_TRACK_BASE "initials"
23
24static GB_ERROR writeHistory(GBDATA *gb_species, const char *stamp, const char *entry) {
25    char     *newContent = GBS_global_string_copy("%s %s", stamp, entry);
26    GB_ERROR  error      = 0;
27    GBDATA   *gb_history = GB_entry(gb_species, "seq_history");
28
29    if (!gb_history) error = GBT_write_string(gb_species, "seq_history", newContent);
30    else {
31        char *oldContent = GB_read_string(gb_history);
32        long  oldSize    = GB_read_string_count(gb_history);
33        long  newSize    = strlen(newContent);
34        long  size       = oldSize+1+newSize+1;
35        char *content    = (char*)malloc(size);
36
37        memcpy(content, newContent, newSize);
38        content[newSize] = '\n';
39        memcpy(content+newSize+1, oldContent, oldSize+1);
40
41        error = GB_write_string(gb_history, content);
42
43        free(content);
44        free(oldContent);
45    }
46
47    free(newContent);
48
49    return error;
50}
51
52static void trackAlignmentChanges(AW_window *aww) {
53    GB_transaction  ta(GLOBAL_gb_main);
54    AW_root        *root           = aww->get_root();
55    char           *ali            = root->awar(AWAR_TRACK_ALI)->read_string();
56    char           *checksum_field = GBS_string_2_key(GBS_global_string("checksum_%s", ali));
57    long            newSpecies     = 0;
58    long            ali_changed    = 0;
59    long            seq_changed    = 0;
60    long            unchanged      = 0;
61    long            species        = GBT_get_species_count(GLOBAL_gb_main);
62    long            count          = 0;
63    GB_ERROR        error          = 0;
64    char           *stamp;
65
66    {
67        char      *initials = root->awar(AWAR_TRACK_INITIALS)->read_string();
68        char       atime[256];
69        time_t     t        = time(0);
70        struct tm *tms      = localtime(&t);
71
72        strftime(atime, 255,"%Y/%m/%d %k:%M", tms);
73        stamp = GBS_global_string_copy("%s %s", atime, initials);
74        free(initials);
75    }
76
77    aw_openstatus(GBS_global_string("Tracking changes in '%s'", ali));
78
79    for (GBDATA *gb_species = GBT_first_species(GLOBAL_gb_main);
80         gb_species && !error;
81         gb_species = GBT_next_species(gb_species))
82    {
83        GBDATA *gb_seq = GBT_read_sequence(gb_species, ali);
84        if (gb_seq) {
85            // has data in wanted alignment
86            const char *seq          = GB_read_char_pntr(gb_seq);
87            long        char_cs      = GBS_checksum(seq, 0, ".-");
88            long        ali_cs       = GBS_checksum(seq, 0, "");
89            char       *char_entry   = GBS_global_string_copy("%lx", char_cs);
90            char       *ali_entry    = GBS_global_string_copy("%lx", ali_cs);
91            const char *save_comment = 0;
92
93            GBDATA *gb_checksum = GB_entry(gb_species, checksum_field);
94            if (!gb_checksum) {
95                newSpecies++;
96                gb_checksum             = GB_create(gb_species, checksum_field, GB_STRING);
97                if (!gb_checksum) error = GB_await_error();
98                else save_comment       = "new";
99            }
100            else {
101                char *oldValue       = GB_read_string(gb_checksum);
102                if (!oldValue) error = GB_await_error();
103                else {
104                    char *comma = strchr(oldValue, ',');
105                    if (!comma) {
106                        error = GBS_global_string("Invalid value '%s' in field '%s'", oldValue, checksum_field);
107                    }
108                    else {
109                        comma[0] = 0;
110                        if (strcmp(char_entry, oldValue) == 0) { // seq checksum is equal
111                            if (strcmp(ali_entry, comma+1) == 0) { // ali checksum is equal
112                                unchanged++;
113                            }
114                            else { // only alignment checksum changed
115                                ali_changed++;
116                                save_comment = "alignment changed";
117                            }
118                        }
119                        else {
120                            seq_changed++;
121                            save_comment = "sequence changed";
122                        }
123                    }
124                    free(oldValue);
125                }
126            }
127
128            if (save_comment) {
129                error             = GB_write_string(gb_checksum, GBS_global_string("%s,%s", char_entry, ali_entry));
130                if (!error) error = writeHistory(gb_species, stamp, GBS_global_string("%s %s", ali, save_comment));
131            }
132
133            free(ali_entry);
134            free(char_entry);
135        }
136        count++;
137        aw_status(count/(double)species);
138    }
139
140    aw_closestatus();
141
142    if (seq_changed) aw_message(GBS_global_string("%li species with changed sequence", seq_changed));
143    if (ali_changed) aw_message(GBS_global_string("%li species with changed alignment", ali_changed));
144    if (newSpecies) aw_message(GBS_global_string("%li new species", newSpecies));
145
146    free(stamp);
147    free(checksum_field);
148    free(ali);
149}
150
151void NT_create_trackAliChanges_Awars(AW_root *root, AW_default properties) {
152    root->awar_string(AWAR_TRACK_ALI, "???", GLOBAL_gb_main);
153    root->awar_string(AWAR_TRACK_INITIALS, GB_getenvUSER(), properties);
154}
155
156AW_window *NT_create_trackAliChanges_window(AW_root *root) {
157    AW_window_simple *aws = new AW_window_simple;
158    aws->init(root, "TRACK_ALI_CHANGES", "Track alignment changes");
159    aws->load_xfig("trackali.fig");
160
161    aws->at("close");
162    aws->callback((AW_CB0)AW_POPDOWN);
163    aws->create_button("CLOSE", "CLOSE", "C");
164
165    aws->at("help");
166    aws->callback( AW_POPUP_HELP,(AW_CL)"track_ali_changes.hlp");
167    aws->create_button("HELP","HELP","H");
168
169    aws->at("initials");
170    aws->create_input_field(AWAR_TRACK_INITIALS);
171   
172    aws->at("ali_sel");
173    awt_create_selection_list_on_ad(GLOBAL_gb_main, aws, AWAR_TRACK_ALI, "*=");
174
175    aws->at("go");
176    aws->callback(trackAlignmentChanges);
177    aws->create_autosize_button("TRACK", "Track changes", "T");
178
179    return aws;
180}
181
182
Note: See TracBrowser for help on using the repository browser.