ARB
NT_trackAliChanges.cxx
Go to the documentation of this file.
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_local.h"
13 
14 #include <awt_sel_boxes.hxx>
15 #include <aw_awar.hxx>
16 #include <aw_root.hxx>
17 #include <aw_msg.hxx>
18 #include <arb_progress.h>
19 #include <arb_strbuf.h>
20 #include <arbdbt.h>
21 #include <ctime>
22 #include <string>
23 #include <list>
24 #include <algorithm>
25 
26 #define AWAR_TRACK_BASE "track/"
27 #define AWAR_TRACK_ALI AWAR_TRACK_BASE "ali"
28 #define AWAR_TRACK_ID AWAR_TRACK_BASE "initials" // [historical]
29 
30 #define SEQ_HISTORY_FIELD "seq_history"
31 
32 using std::string;
33 using std::list;
34 
35 static GB_ERROR writeHistory(GBDATA *gb_species, const char *stamp, const char *entry) {
36  char *newContent = GBS_global_string_copy("%s %s", stamp, entry);
38  GBDATA *gb_history = GB_entry(gb_species, SEQ_HISTORY_FIELD);
39 
40  if (!gb_history) error = GBT_write_string(gb_species, SEQ_HISTORY_FIELD, newContent);
41  else {
42  size_t oldSize = GB_read_string_count(gb_history);
43  size_t newSize = strlen(newContent);
44 
45  GBS_strstruct content(oldSize+newSize+3);
46  content.ncat(newContent, newSize);
47  content.put('\n');
48  content.ncat(GB_read_char_pntr(gb_history), oldSize);
49 
50  error = GB_write_string(gb_history, content.get_data());
51  }
52 
53  free(newContent);
54 
55  return error;
56 }
57 
58 static void trackAlignmentChanges(AW_window *aww) {
60 
61  AW_root *root = aww->get_root();
62  char *ali = root->awar(AWAR_TRACK_ALI)->read_string();
63  char *checksum_field = GBS_string_2_key(GBS_global_string("checksum_%s", ali));
65  char *stamp;
66 
67  {
68  const char *sessionID = root->awar(AWAR_TRACK_ID)->read_char_pntr();
69  char atime[256];
70  time_t t = time(NULp);
71  struct tm *tms = localtime(&t);
72 
73  strftime(atime, 255, "%Y/%m/%d %k:%M", tms);
74  stamp = GBS_global_string_copy("%s %s", atime, sessionID);
75  }
76 
77  arb_progress progress(GBS_global_string("Tracking changes in '%s'", ali), GBT_get_species_count(GLOBAL.gb_main));
78 
79  // add changekeys for generated fields:
82 
83  size_t newSpecies = 0;
84  size_t ali_changed = 0;
85  size_t seq_changed = 0;
86  size_t unchanged = 0;
87 
88  for (GBDATA *gb_species = GBT_first_species(GLOBAL.gb_main);
89  gb_species && !error;
90  gb_species = GBT_next_species(gb_species))
91  {
92  GBDATA *gb_seq = GBT_find_sequence(gb_species, ali);
93  if (gb_seq) {
94  // has data in wanted alignment
95  const char *seq = GB_read_char_pntr(gb_seq);
96  long char_cs = GBS_checksum(seq, 0, ".-");
97  long ali_cs = GBS_checksum(seq, 0, "");
98  char *char_entry = GBS_global_string_copy("%lx", char_cs);
99  char *ali_entry = GBS_global_string_copy("%lx", ali_cs);
100  const char *save_comment = NULp;
101 
102  GBDATA *gb_checksum = GB_entry(gb_species, checksum_field);
103  if (!gb_checksum) {
104  newSpecies++;
105  gb_checksum = GB_create(gb_species, checksum_field, GB_STRING);
106  if (!gb_checksum) error = GB_await_error();
107  else save_comment = "new";
108  }
109  else {
110  char *oldValue = GB_read_string(gb_checksum);
111  if (!oldValue) error = GB_await_error();
112  else {
113  char *comma = strchr(oldValue, ',');
114  if (!comma) {
115  error = GBS_global_string("Invalid value '%s' in field '%s'", oldValue, checksum_field);
116  }
117  else {
118  comma[0] = 0;
119  if (strcmp(char_entry, oldValue) == 0) { // seq checksum is equal
120  if (strcmp(ali_entry, comma+1) == 0) { // ali checksum is equal
121  unchanged++;
122  }
123  else { // only alignment checksum changed
124  ali_changed++;
125  save_comment = "alignment changed";
126  }
127  }
128  else {
129  seq_changed++;
130  save_comment = "sequence changed";
131  }
132  }
133  free(oldValue);
134  }
135  }
136 
137  if (save_comment) {
138  error = GB_write_string(gb_checksum, GBS_global_string("%s,%s", char_entry, ali_entry));
139  if (!error) error = writeHistory(gb_species, stamp, GBS_global_string("%s %s", ali, save_comment));
140  }
141 
142  if (error) {
143  error = GBS_global_string("%s (%s)", error, GBT_get_name_or_description(gb_species));
144  }
145 
146  free(ali_entry);
147  free(char_entry);
148  }
149  progress.inc_and_check_user_abort(error);
150  }
151 
152  if (error) aw_message(error);
153  else {
154  struct ReportLine {
155  string tag;
156  size_t amount;
157  ReportLine(string tag_, size_t amount_) : tag(tag_), amount(amount_) { }
158  };
159 
160  list<ReportLine> reports;
161  if (newSpecies) reports.push_back(ReportLine("previously untracked", newSpecies));
162  if (unchanged) reports.push_back(ReportLine("unchanged", unchanged));
163  if (ali_changed) reports.push_back(ReportLine("only alignment changed", ali_changed));
164  if (seq_changed) reports.push_back(ReportLine("sequence changed", seq_changed));
165 
166  if (!reports.empty()) {
167  size_t tagMaxLen = 0;
168  size_t amountMax = 0;
169  for (list<ReportLine>::const_iterator r = reports.begin(); r != reports.end(); ++r) {
170  tagMaxLen = std::max(tagMaxLen, r->tag.length());
171  amountMax = std::max(amountMax, r->amount);
172  }
173 
174  size_t amountMaxLen = std::to_string(amountMax).length();
175  GBS_strstruct msg;
176  for (list<ReportLine>::const_iterator r = reports.begin(); r != reports.end(); ++r) {
177  msg.catPadded(GBS_global_string("%s:", r->tag.c_str()), tagMaxLen+2);
178  msg.nprintf(amountMaxLen, GBS_global_string("%*zu", int(amountMaxLen), r->amount));
179  msg.cat(" species\n");
180  }
181  msg.cut_tail(1); // remove final LF
182  aw_message(msg.get_data());
183  }
184  }
185 
186  free(stamp);
187  free(checksum_field);
188  free(ali);
189 }
190 
192  root->awar_string(AWAR_TRACK_ALI, "???", GLOBAL.gb_main);
193  root->awar_string(AWAR_TRACK_ID, GB_getenvUSER(), properties);
194 }
195 
197  AW_window_simple *aws = new AW_window_simple;
198  aws->init(root, "TRACK_ALI_CHANGES", "Track alignment changes");
199  aws->load_xfig("trackali.fig");
200 
201  aws->at("close");
202  aws->callback(AW_POPDOWN);
203  aws->create_button("CLOSE", "CLOSE", "C");
204 
205  aws->at("help");
206  aws->callback(makeHelpCallback("track_ali_changes.hlp"));
207  aws->create_button("HELP", "HELP", "H");
208 
209  aws->at("id");
210  aws->create_input_field(AWAR_TRACK_ID);
211 
212  aws->at("ali_sel");
214 
215  aws->at("go");
216  aws->callback(trackAlignmentChanges);
217  aws->create_autosize_button("TRACK", "Track changes", "T");
218 
219  return aws;
220 }
221 
222 
const char * GB_ERROR
Definition: arb_core.h:25
void cut_tail(size_t byte_count)
Definition: arb_strbuf.h:145
static GB_ERROR writeHistory(GBDATA *gb_species, const char *stamp, const char *entry)
return string(buffer, length)
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
Definition: arbdb.cxx:1387
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:720
void GB_warning_if(const char *message)
Definition: arb_msg.cxx:541
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
char * GBS_string_2_key(const char *str)
Definition: adstring.cxx:52
void cat(const char *from)
Definition: arb_strbuf.h:199
#define AWAR_TRACK_ALI
#define SEQ_HISTORY_FIELD
FILE * seq
Definition: rns.c:46
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
GB_ERROR GBT_add_new_species_changekey(GBDATA *gb_main, const char *name, GB_TYPES type)
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:916
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
#define AWAR_TRACK_ID
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
GBDATA * GB_create(GBDATA *father, const char *key, GB_TYPES type)
Definition: arbdb.cxx:1781
static void error(const char *msg)
Definition: mkptypes.cxx:96
AW_window * NT_create_trackAliChanges_window(AW_root *root)
char * read_string() const
Definition: AW_awar.cxx:198
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
GBDATA * GBT_find_sequence(GBDATA *gb_species, const char *aliname)
Definition: adali.cxx:718
AW_DB_selection * awt_create_ALI_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname, const char *ali_type_match)
void ncat(const char *from, size_t count)
Definition: arb_strbuf.h:189
void NT_create_trackAliChanges_Awars(AW_root *root, AW_default properties)
static void trackAlignmentChanges(AW_window *aww)
GB_CSTR GB_getenvUSER(void)
Definition: adsocket.cxx:545
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
Definition: adtools.cxx:451
void nprintf(size_t maxlen, const char *templat,...) __ATTR__FORMAT_MEMBER(2)
Definition: arb_strbuf.cxx:29
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:909
int catPadded(const char *from, size_t paddedWidth)
Definition: arb_strbuf.h:212
GBDATA * GBT_first_species(GBDATA *gb_main)
Definition: aditem.cxx:124
uint32_t GBS_checksum(const char *seq, int ignore_case, const char *exclude)
Definition: adstring.cxx:352
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
AW_root * get_root()
Definition: aw_window.hxx:359
GBDATA * GBT_next_species(GBDATA *gb_species)
Definition: aditem.cxx:128
#define NULp
Definition: cxxforward.h:116
GBDATA * gb_main
Definition: NT_local.h:37
const char * get_data() const
Definition: arb_strbuf.h:120
long GBT_get_species_count(GBDATA *gb_main)
Definition: aditem.cxx:207
GB_transaction ta(gb_var)
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
Definition: arbdb.cxx:904
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
GB_CSTR GBT_get_name_or_description(GBDATA *gb_item)
Definition: aditem.cxx:459
GBDATA * GB_entry(GBDATA *father, const char *key)
Definition: adquery.cxx:334
void inc_and_check_user_abort(GB_ERROR &error)
Definition: arb_progress.h:332
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
NT_global GLOBAL
Definition: NT_main.cxx:46
void put(char c)
Definition: arb_strbuf.h:174
#define max(a, b)
Definition: f2c.h:154