ARB
graph_aligner_gui.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : graph_aligner_gui.cxx //
4 // Purpose : //
5 // //
6 // Coded by Elmar Pruesse in October 2008 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #include "graph_aligner_gui.hxx"
13 
14 #include "ed4_defs.hxx"
15 
16 // need to use AlignDataAccess defined here to get selected species
17 #include <fast_aligner.hxx>
18 
19 #include <aw_awars.hxx>
20 #include <aw_global_awars.hxx>
21 #include <aw_msg.hxx>
22 #include <aw_root.hxx>
23 #include <awt_sel_boxes.hxx>
24 #include <awt_config_manager.hxx>
25 #include <servercntrl.h>
26 #include <PT_com.h>
27 #include <client.h>
28 #include <arbdbt.h>
29 #include <arb_strbuf.h>
30 #include <arb_misc.h>
31 #include <arb_file.h>
32 
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 
36 #include <unistd.h>
37 
38 #include <string>
39 #include <sstream>
40 #include <iostream>
41 #include <vector>
42 
43 using std::cerr;
44 using std::cout;
45 using std::endl;
46 
47 #define ga_assert(cond) arb_assert(cond)
48 
49 #define GA_AWAR_ROOT "sina/"
50 #define GA_AWAR_TEMP "tmp/" GA_AWAR_ROOT
51 
52 #define GA_AWAR_CMD GA_AWAR_ROOT "cmd"
53 #define GA_AWAR_TGT GA_AWAR_ROOT "target"
54 #define GA_AWAR_SAI GA_AWAR_ROOT "sai"
55 #define GA_AWAR_ALIGNMENT GA_AWAR_ROOT "alignment"
56 #define GA_AWAR_PROTECTION GA_AWAR_ROOT "protection"
57 #define GA_AWAR_TURN_CHECK GA_AWAR_ROOT "turncheck"
58 #define GA_AWAR_REALIGN GA_AWAR_ROOT "realign"
59 #define GA_AWAR_MATCH_SCORE GA_AWAR_ROOT "match_score"
60 #define GA_AWAR_MISMATCH_SCORE GA_AWAR_ROOT "mismatch_score"
61 #define GA_AWAR_GAP_PEN GA_AWAR_ROOT "gap_pen"
62 #define GA_AWAR_GAP_EXT GA_AWAR_ROOT "gap_ext"
63 #define GA_AWAR_ADVANCED GA_AWAR_ROOT "advanced"
64 #define GA_AWAR_FS_MIN GA_AWAR_ROOT "fs_min"
65 #define GA_AWAR_FS_MAX GA_AWAR_ROOT "fs_max"
66 #define GA_AWAR_FS_MSC GA_AWAR_ROOT "fs_msc"
67 #define GA_AWAR_MIN_FULL GA_AWAR_ROOT "min_full"
68 #define GA_AWAR_FULL_MINLEN GA_AWAR_ROOT "full_minlen"
69 #define GA_AWAR_OVERHANG GA_AWAR_ROOT "overhang"
70 #define GA_AWAR_THREADS GA_AWAR_ROOT "threads"
71 #define GA_AWAR_QSIZE GA_AWAR_ROOT "qsize"
72 #define GA_AWAR_KMER_LEN GA_AWAR_ROOT "kmer_len"
73 #define GA_AWAR_KMER_MM GA_AWAR_ROOT "kmer_mm"
74 #define GA_AWAR_MIN_LEN GA_AWAR_ROOT "min_len"
75 #define GA_AWAR_WEIGHT GA_AWAR_ROOT "weight"
76 #define GA_AWAR_INSERT GA_AWAR_ROOT "insert"
77 #define GA_AWAR_LOWERCASE GA_AWAR_ROOT "lowercase"
78 #define GA_AWAR_AUTOFILTER GA_AWAR_ROOT "autofilter"
79 #define GA_AWAR_KMER_NOREL GA_AWAR_ROOT "kmer_norel"
80 #define GA_AWAR_KMER_NOFAST GA_AWAR_ROOT "kmer_nofast"
81 #define GA_AWAR_SHOW_DIST GA_AWAR_ROOT "show_dist"
82 #define GA_AWAR_SHOW_DIFF GA_AWAR_ROOT "show_diff"
83 #define GA_AWAR_COLOR GA_AWAR_ROOT "color"
84 #define GA_AWAR_GENE_START GA_AWAR_ROOT "gene_start"
85 #define GA_AWAR_GENE_END GA_AWAR_ROOT "gene_end"
86 #define GA_AWAR_FS_COVER_GENE GA_AWAR_ROOT "fs_cover_gene"
87 #define GA_AWAR_USED_RELS GA_AWAR_ROOT "write_used_rels"
88 #define GA_AWAR_CALC_IDENTITY GA_AWAR_ROOT "calc_idty"
89 #define GA_AWAR_NOWARN_START GA_AWAR_ROOT "nowarn_start"
90 #define GA_AWAR_REFDB_MODE GA_AWAR_ROOT "refdb_mode"
91 #define GA_AWAR_REFDB GA_AWAR_ROOT "refdb"
92 #define GA_AWAR_REFDB_SELECT GA_AWAR_TEMP "refdb"
93 
94 enum RefDbMode {
95  REF_EXPLICIT, // use explicitly specified database
96  REF_LAST_SAVE, // use last saved state of loaded database
97  REF_CURRENT, // use current state of loaded database
98 };
99 
100 static void refDbModeChanged_cb(AW_root *root) {
102  AW_awar *awar_refdb = root->awar(GA_AWAR_REFDB);
103 
104  switch (mode) {
105  case REF_EXPLICIT: {
106  const char *refdb = awar_refdb->read_char_pntr();
107  if (!GB_is_readablefile(refdb)) {
108  const char *refdb_sel = root->awar(GA_AWAR_REFDB_SELECT)->read_char_pntr();
109  if (GB_is_readablefile(refdb_sel)) {
110  awar_refdb->write_string(refdb_sel);
111  }
112  else {
113  aw_message("Please select a reference database");
114  }
115  }
116  break;
117  }
118  case REF_LAST_SAVE: {
119  const char *db_name = root->awar(AWAR_SAVED_DB_PATH)->read_char_pntr();
120  if (db_name[0] == 0) { // happens when editor runs standalone
121  aw_message("Failed to detect name of current database - please select manually");
122  }
123  awar_refdb->write_string(db_name);
124  break;
125  }
126  case REF_CURRENT: {
127  awar_refdb->write_string(":");
128  break;
129  }
130  }
131 }
132 
133 static void newRefDbSelected_cb(AW_root *root) {
134  const char *refdb_sel = root->awar(GA_AWAR_REFDB_SELECT)->read_char_pntr();
135 
136  if (GB_is_readablefile(refdb_sel)) {
138  root->awar(GA_AWAR_REFDB)->write_string(refdb_sel);
139  }
140  else {
142  }
143 }
144 
146  const char *sinaCmd = "arb_sina.sh";
147  root->awar_string(GA_AWAR_CMD, sinaCmd, db1);
148  root->awar_int (GA_AWAR_TGT, 2, db1);
149  root->awar_int (AWAR_PT_SERVER, 0, db1);
150  root->awar_string(GA_AWAR_SAI, "", db1);
151  root->awar_int (GA_AWAR_PROTECTION, 0, db1);
152  root->awar_int (GA_AWAR_TURN_CHECK, 1, db1);
153  root->awar_int (GA_AWAR_REALIGN, 1, db1);
154  root->awar_float (GA_AWAR_GAP_PEN, 5.0, db1);
155  root->awar_float (GA_AWAR_GAP_EXT, 2.0, db1);
156  root->awar_float (GA_AWAR_MATCH_SCORE, 2.0, db1);
157  root->awar_float (GA_AWAR_MISMATCH_SCORE, -1.0, db1);
158  root->awar_int (GA_AWAR_ADVANCED, 0, db1);
159  root->awar_int (GA_AWAR_FS_MIN, 40, db1);
160  root->awar_int (GA_AWAR_FS_MAX, 40, db1);
161  root->awar_float (GA_AWAR_FS_MSC, .7, db1);
162  root->awar_int (GA_AWAR_MIN_FULL, 1, db1);
163  root->awar_int (GA_AWAR_FULL_MINLEN, 1400, db1);
164  root->awar_string(GA_AWAR_OVERHANG, "attach", db1);
165  root->awar_int (GA_AWAR_THREADS, 1, db1);
166  root->awar_int (GA_AWAR_QSIZE, 1, db1);
167  root->awar_int (GA_AWAR_KMER_LEN, 10, db1);
168  root->awar_int (GA_AWAR_KMER_MM, 0, db1);
169  root->awar_int (GA_AWAR_MIN_LEN, 150, db1);
170  root->awar_float (GA_AWAR_WEIGHT, 1, db1);
171  root->awar_string(GA_AWAR_INSERT, "shift", db1);
172  root->awar_string(GA_AWAR_LOWERCASE, "none", db1);
173  root->awar_string(GA_AWAR_AUTOFILTER, "", db1);
174  root->awar_int (GA_AWAR_KMER_NOREL, 0, db1);
175  root->awar_int (GA_AWAR_KMER_NOFAST, 0, db1);
176  root->awar_int (GA_AWAR_SHOW_DIST, 0, db1);
177  root->awar_int (GA_AWAR_SHOW_DIFF, 0, db1);
178  root->awar_int (GA_AWAR_COLOR, 1, db1);
179  root->awar_int (GA_AWAR_GENE_START, 0, db1);
180  root->awar_int (GA_AWAR_GENE_END, 0, db1);
181  root->awar_int (GA_AWAR_FS_COVER_GENE, 0, db1);
182  root->awar_int (GA_AWAR_USED_RELS, 0, db1);
183  root->awar_int (GA_AWAR_CALC_IDENTITY, 0, db1);
184  root->awar_int (GA_AWAR_NOWARN_START, 0, db1);
185 
186  AW_awar *awar_mode = root->awar_int (GA_AWAR_REFDB_MODE, REF_CURRENT, db1);
187  root->awar_string (GA_AWAR_REFDB, ":", db1);
188  AW_awar *awar_select = root->awar_string(GA_AWAR_REFDB_SELECT, "", db1);
189 
190  awar_mode->add_callback(makeRootCallback(refDbModeChanged_cb));
191  awar_select->add_callback(makeRootCallback(newRefDbSelected_cb));
192 }
193 
197 };
199 
202  const char *id; // as define by SINA
203 };
204 
206  // order matters: first supported version will be used.
207 
208  { ARB_7_1, "ARB7.1" }, // only defined in patched version delivered with arb
209  { ARB_5_99, "ARB5.99" }, // supported at least by sina 1.3 up to 1.7.2
210 
211  { NO_INTERFACE, "<none>" }, // version=sentinel
212 };
213 
214 static const char *get_interface_id(SinaArbInterfaceVersion version) {
215  for (int v = 0; ; ++v) {
216  const sina_arb_interface_def& sina_interface = supported_sina_versions[v];
217  if (sina_interface.version == version) {
218  return sina_interface.id;
219  }
220  }
222 }
223 
225 
227  const char *sinaName = awr->awar(GA_AWAR_CMD)->read_char_pntr();
228  char *sina = ARB_executable(sinaName, GB_getenv("PATH"));
229  const char *fail_reason = NULp;
230  std::string tested_interfaces = "";
231 
233 
234  if (sina) {
236  char *description = GBS_global_string_copy("the sina executable derived from\n"
237  "- gui property '%s' and\n"
238  "- environment variable PATH", sinaName);
239  ARB_warn_about_unwanted_chars(sina, description);
240  free(description);
241  }
242 
243  for (int v = 0; ; ++v) {
244  const sina_arb_interface_def& sina_interface = supported_sina_versions[v];
245 
246  if (sina_interface.version == NO_INTERFACE) {
247  if (fail_reason) fail_reason = GBS_global_string("%s (this ARB supports these interface versions: %s)", fail_reason, tested_interfaces.c_str());
248  break;
249  }
250 
251  int exitstatus = system(GBS_global_string("%s --has-cli-vers %s", sina, sina_interface.id));
252  exitstatus = WEXITSTATUS(exitstatus);
253 
254  if (exitstatus == EXIT_FAILURE) {
255  fail_reason = "Incompatible SINA and ARB versions";
256 
257  if (!tested_interfaces.empty()) tested_interfaces += ' ';
258  tested_interfaces += sina_interface.id;
259  }
260  else {
261  if (exitstatus == EXIT_SUCCESS) {
262  used_sina_interface = sina_interface.version;
263  fail_reason = NULp;
264 
265  fprintf(stdout, "Using SINA-ARB interface version '%s'%s\n", sina_interface.id, v>0 ? " (old)" : "");
266  }
267  else {
268  fail_reason = GBS_global_string("Could not execute SINA binary '%s' (exitstatus was %i)",
269  sinaName, exitstatus);
270  }
271  break; // either found compatible version or failed completely -> stop
272  }
273  }
274 
275  free(sina);
276  }
277  else {
278  fail_reason = GBS_global_string("'%s' not found", sinaName);
279  }
280 
281  return fail_reason;
282 }
283 
285  GB_ERROR fail_reason = detect_sina_version(awr);
286 
287  if (fail_reason) {
288  fprintf(stderr, "Note: SINA (SILVA Aligner) disabled (Reason: %s)\n", fail_reason);
289  }
290 
291  return fail_reason ? AWM_DISABLED : AWM_ALL;
292 }
293 
294 inline const char *stream2static(const std::stringstream& str) {
295  return GBS_static_string(str.str().c_str());
296 }
297 
298 inline const char *empty_as_none(const char *sainame) {
299  // see http://bugs.arb-home.de/ticket/519
300  if (sainame && !sainame[0]) sainame = "none";
301  return sainame;
302 }
303 
304 static void sina_start(AW_window *window, const AlignDataAccess *data_access) {
305  cerr << "Starting SINA..." << endl;
306 
307  AW_root *root = window->get_root();
308  GB_ERROR gb_error = NULp;
309 
310  // make string from pt server selection
311  const char *pt_server = NULp;
312  {
313  int pt = root->awar(AWAR_PT_SERVER)->read_int();
314  if (pt == -1) { // do NOT use ptserver (aka "use sina internal family search")
315  if (used_sina_interface == ARB_5_99) {
316  gb_error = "internal SINA family search is not available with your SINA version";
317  }
318  }
319  else {
320  std::stringstream ptnam;
321  ptnam << "ARB_PT_SERVER" << pt;
322 
323  pt_server = GBS_read_arb_tcp(ptnam.str().c_str());
324  if (!pt_server) {
325  gb_error = GBS_global_string("Unable to find definition for chosen PT-server\n(Reason: %s)", GB_await_error());
326  }
327  else {
328  const char *pt_db = pt_server + strlen(pt_server) + 1;
329  pt_db += strlen(pt_db)+3;
330 
331  // start pt server if necessary
332  gb_error = arb_look_and_start_server(AISC_MAGIC_NUMBER, ptnam.str().c_str());
333  if (gb_error) {
334  std::stringstream tmp;
335  tmp << "Cannot contact PT server. Aborting" << endl
336  << " ID: \"" << tmp.str().c_str()
337  << "\" PORT: \"" << pt_server
338  << "\" DB: \"" << pt_db << endl
339  << "\" GBERROR: \"" << gb_error << "\"" << endl;
340  gb_error = stream2static(tmp);
341  }
342  }
343  }
344  }
345 
346  if (!gb_error) {
347  // create temporary file
348  char* tmpfile;
349  FILE* tmpfile_F;
350  {
351  char* tmpfile_tpl = GB_unique_filename("sina_select", "tmp");
352  tmpfile_F = GB_fopen_tempfile(tmpfile_tpl, "w", &tmpfile);
353  free(tmpfile_tpl);
354  }
355 
356  if (!tmpfile_F) {
357  std::stringstream tmp;
358  tmp << "Error: Unable to create temporary file \"" << tmpfile << "\"!";
359  gb_error = stream2static(tmp);
360  }
361  else {
362  GB_remove_on_exit(tmpfile);
363  GBDATA *gb_main = data_access->gb_main;
364 
365  std::vector<std::string> spec_names;
366  switch (root->awar(GA_AWAR_TGT)->read_int()) {
367  case 0: { // current
368  char *spec_name = root->awar(AWAR_SPECIES_NAME)->read_string();
369  if (spec_name) {
370  fwrite(spec_name, strlen(spec_name), 1, tmpfile_F);
371  fwrite("\n", 1, 1, tmpfile_F);
372  }
373  else {
374  gb_error = "Unable to get name of currently active species";
375  }
376  free(spec_name);
377  break;
378  }
379  case 1: { // selected
380  GB_begin_transaction(gb_main);
381  int num_selected = 0;
382  for (GBDATA *gb_spec = data_access->get_first_selected_species(&num_selected);
383  gb_spec;
384  gb_spec = data_access->get_next_selected_species())
385  {
386  GBDATA *gbd_name = GB_find(gb_spec, "name", SEARCH_CHILD);
387  if (gbd_name) {
388  const char *str = GB_read_char_pntr(gbd_name);
389  fwrite(str, strlen(str), 1, tmpfile_F);
390  fwrite("\n", 1, 1, tmpfile_F);
391  }
392  }
393  GB_commit_transaction(gb_main);
394  break;
395  }
396  case 2: { // marked
397  GB_begin_transaction(gb_main);
398  for (GBDATA *gb_spec = GBT_first_marked_species(gb_main);
399  gb_spec; gb_spec = GBT_next_marked_species(gb_spec)) {
400  GBDATA *gbd_name = GB_find(gb_spec, "name", SEARCH_CHILD);
401  if (gbd_name) {
402  const char *str = GB_read_char_pntr(gbd_name);
403  fwrite(str, strlen(str), 1, tmpfile_F);
404  fwrite("\n", 1, 1, tmpfile_F);
405  }
406  }
407  GB_commit_transaction(gb_main);
408  break;
409  }
410  }
411  fclose(tmpfile_F);
412 
413  if (!gb_error) {
414  // build command line
415  GBS_strstruct cl(2000);
416 
417  cl.cat(root->awar(GA_AWAR_CMD)->read_char_pntr());
418  cl.cat(" -i :");
419 
420  switch (used_sina_interface) {
421  case ARB_5_99: cl.cat(" --ptdb :"); break;
422  case ARB_7_1:
423  cl.cat(" --out :");
424  cl.cat(" --db "); cl.cat(root->awar(GA_AWAR_REFDB)->read_char_pntr());
425  if (root->awar(GA_AWAR_NOWARN_START)->read_int()) cl.cat(" --dont-expect-start");
426  if (root->awar(GA_AWAR_CALC_IDENTITY)->read_int()) cl.cat(" --calc-idty");
427  cl.cat(" --default-alignment "); cl.cat(data_access->alignment_name.c_str()); // always use alignment used in editor
428  break;
429  }
430 
431  if (pt_server) {
432  cl.cat(" --ptport "); cl.cat(pt_server);
433  if (used_sina_interface == ARB_7_1) {
434  cl.cat(" --fs-engine "); cl.cat("pt-server");
435  }
436  }
437  else { // use sina internal search
439  cl.cat(" --fs-engine "); cl.cat("internal");
440  }
441 
442  cl.cat(" --turn "); cl.cat(root->awar(GA_AWAR_TURN_CHECK)->read_int() ? "all" : "none");
443  cl.cat(" --overhang "); cl.cat(root->awar(GA_AWAR_OVERHANG)->read_char_pntr());
444  cl.cat(" --filter "); cl.cat(empty_as_none(root->awar(GA_AWAR_SAI)->read_char_pntr()));
445  cl.cat(" --fs-min "); cl.putlong(root->awar(GA_AWAR_FS_MIN)->read_int());
446  cl.cat(" --fs-msc "); cl.putfloat(root->awar(GA_AWAR_FS_MSC)->read_float());
447  cl.cat(" --fs-max "); cl.putlong(root->awar(GA_AWAR_FS_MAX)->read_int());
448  cl.cat(" --fs-req 1"); // hardcoded to 1 - uses stricter requirement for full-length sequences
449  cl.cat(" --fs-req-full "); cl.putlong(root->awar(GA_AWAR_MIN_FULL)->read_int());
450  cl.cat(" --fs-full-len "); cl.putlong(root->awar(GA_AWAR_FULL_MINLEN)->read_int());
451  cl.cat(" --fs-kmer-len "); cl.putlong(root->awar(GA_AWAR_KMER_LEN)->read_int());
452  cl.cat(" --fs-kmer-mm "); cl.putlong(root->awar(GA_AWAR_KMER_MM)->read_int()); // @@@ only with ptserver -> document + add 2 gui
453  cl.cat(" --fs-min-len "); cl.putlong(root->awar(GA_AWAR_MIN_LEN)->read_int());
454  cl.cat(" --fs-weight "); cl.putfloat(root->awar(GA_AWAR_WEIGHT)->read_float());
455  cl.cat(" --pen-gap "); cl.putfloat(root->awar(GA_AWAR_GAP_PEN)->read_float());
456  cl.cat(" --pen-gapext "); cl.putfloat(root->awar(GA_AWAR_GAP_EXT)->read_float());
457  cl.cat(" --match-score "); cl.putfloat(root->awar(GA_AWAR_MATCH_SCORE)->read_float());
458  cl.cat(" --mismatch-score "); cl.putfloat(root->awar(GA_AWAR_MISMATCH_SCORE)->read_float());
459  cl.cat(" --prot-level "); cl.putlong(root->awar(GA_AWAR_PROTECTION)->read_int());
460  cl.cat(" --select-file "); cl.cat(tmpfile);
461  cl.cat(" --insertion "); cl.cat(root->awar(GA_AWAR_INSERT)->read_char_pntr());
462  cl.cat(" --lowercase "); cl.cat(root->awar(GA_AWAR_LOWERCASE)->read_char_pntr());
463  cl.cat(" --auto-filter-field "); cl.cat_sQuoted(root->awar(GA_AWAR_AUTOFILTER)->read_char_pntr()); // note: default value passed to sina 1.3 was 'none' (w/o quotes)
464  cl.cat(" --gene-start "); cl.putlong(root->awar(GA_AWAR_GENE_START)->read_int());
465  cl.cat(" --gene-end "); cl.putlong(root->awar(GA_AWAR_GENE_END)->read_int());
466  cl.cat(" --fs-cover-gene "); cl.putlong(root->awar(GA_AWAR_FS_COVER_GENE)->read_int());
467 
468 
469  if (root->awar(GA_AWAR_KMER_NOREL)->read_int()) cl.cat(" --fs-kmer-norel ");
470  if (root->awar(GA_AWAR_KMER_NOFAST)->read_int()) cl.cat(" --fs-kmer-no-fast ");
471  if (root->awar(GA_AWAR_SHOW_DIST)->read_int()) cl.cat(" --show-dist ");
472  if (root->awar(GA_AWAR_SHOW_DIFF)->read_int()) cl.cat(" --show-diff ");
473  if (root->awar(GA_AWAR_COLOR)->read_int()) cl.cat(" --color");
474  if (root->awar(GA_AWAR_REALIGN)->read_int()) cl.cat(" --realign");
475  if (root->awar(GA_AWAR_USED_RELS)->read_int()) cl.cat(" --write-used-rels");
476 
477  gb_error = GB_xcmd(cl.get_data(), XCMD_ASYNC_WAITKEY);
478  }
479 
480  if (!gb_error) aw_message("SINA finished aligning.");
481  }
482  free(tmpfile);
483  }
484 
485  aw_message_if(gb_error);
486 }
487 
488 
489 
490 static char* filter_posvar_SAI_for_ali(GBDATA *gb_extended, const char *ali_name) {
491  char *result = NULp;
492  char *typePath = GBS_global_string_copy("%s/_TYPE", ali_name);
493  GBDATA *gbd = GB_search(gb_extended, typePath, GB_FIND);
494  if (gbd) {
495  const char* type = GB_read_char_pntr(gbd);
496  if (type && strncmp("PV", type, 2) == 0) {
497  gbd = GB_find(gb_extended, "name", SEARCH_CHILD);
498  result = GB_read_string(gbd);
499  }
500  }
501  free(typePath);
502  return result;
503 }
504 
506  // both
507  { GA_AWAR_TGT, "target" },
508  { GA_AWAR_OVERHANG, "overhang" },
509  { GA_AWAR_INSERT, "insertions" },
510  { GA_AWAR_LOWERCASE, "lowercase" },
511  { GA_AWAR_WEIGHT, "weight" },
512  { GA_AWAR_FULL_MINLEN, "fullminlen" },
513 
514  // advanced only
515  { GA_AWAR_SAI, "sai" },
516  { GA_AWAR_AUTOFILTER, "autofilter" },
517  { GA_AWAR_TURN_CHECK, "turncheck" },
518  { GA_AWAR_REALIGN, "realign" },
519  { GA_AWAR_GAP_PEN, "gappen" },
520  { GA_AWAR_GAP_EXT, "gapext" },
521  { GA_AWAR_MATCH_SCORE, "matchscore" },
522  { GA_AWAR_MISMATCH_SCORE, "mismatchscore" },
523  { GA_AWAR_FS_MIN, "fs_min" },
524  { GA_AWAR_FS_MSC, "fs_minscore" },
525  { GA_AWAR_FS_MAX, "fs_min" },
526  { GA_AWAR_MIN_FULL, "minfull" },
527  { GA_AWAR_KMER_LEN, "kmerlen" },
528  { GA_AWAR_KMER_MM, "kmermm" },
529  { GA_AWAR_MIN_LEN, "refminlen" },
530  { GA_AWAR_GENE_START, "genestart" },
531  { GA_AWAR_GENE_END, "geneend" },
532  { GA_AWAR_FS_COVER_GENE, "fs_covergene" },
533  { GA_AWAR_USED_RELS, "write_used_rels" },
534  { GA_AWAR_CALC_IDENTITY, "calc_identity" },
535  { GA_AWAR_KMER_NOFAST, "kmernofast" },
536  { GA_AWAR_KMER_NOREL, "kmernorel" },
537 
538  // both
539  { GA_AWAR_SHOW_DIFF, "showdiff" },
540  { GA_AWAR_COLOR, "color" },
541  { GA_AWAR_SHOW_DIST, "showdist" },
542 
543  { NULp, NULp }
544 };
545 
546 static void accept_selected_ref_db(AW_window *aww, const char * const *awar_filename) {
547  AW_root *root = aww->get_root();
548  char *filename = root->awar(*awar_filename)->read_string();
549 
550  if (GB_is_readablefile(filename)) {
551  AW_awar *awar_refdb_sel = root->awar(GA_AWAR_REFDB_SELECT);
552  awar_refdb_sel->write_string(filename);
553  aww->hide();
554  }
555 
556  free(filename);
557 }
558 
560  static char *awar_name = NULp; // do not free, bound to callback
561  return awt_create_load_box(aw_root,
562  "Select",
563  "SINA reference database",
564  ".", "arb", &awar_name,
565  makeWindowCallback(accept_selected_ref_db, (const char*const*)&awar_name));
566 }
567 
568 
569 static void sina_select_ref_db(AW_window *aww) {
570  static AW_window *aw_ref_db_selection = NULL;
571 
572  if (!aw_ref_db_selection) {
573  AW_root *root = aww->get_root();
574  aw_ref_db_selection = create_ref_db_selection_window(root);
575  }
576 
577  aw_ref_db_selection->activate();
578 }
579 
580 
581 static SinaArbInterfaceVersion gui_sina_interface = NO_INTERFACE; // interface used in GUI
582 
583 static void sina_cmd_changed_cb(AW_root *awr) {
584  GB_ERROR fail_reason = detect_sina_version(awr);
585 
586  if (fail_reason) {
587  aw_message(fail_reason);
588  }
589  else {
591  aw_message("The GUI does not match the used sina version!\n"
592  "Please save properties and restart the editor.");
593  }
594  aw_message(GBS_global_string("Using sina-arb interface '%s'", get_interface_id(used_sina_interface)));
595  }
596 }
597 
598 static AW_window_simple* new_sina_simple(AW_root *root, const AlignDataAccess *alignData, bool adv) {
599  const int hgap = 10;
600  AW_window_simple *aws = new AW_window_simple;
601 
605  }
606 
607  aws->reset_layout("20220422");
608  aws->init(root, adv ? "XSINA" : "SINA", "SINA (SILVA Incremental Aligner)");
609 
610  aws->button_length(12);
611  aws->at(10, 10);
612  aws->auto_space(5, 5);
613 
614  int closex, closey; aws->get_at_position(&closex, &closey);
615 
616  aws->callback(AW_POPDOWN);
617  aws->create_button("CLOSE", "CLOSE", "O");
618 
619  int closex2 = aws->get_at_xposition();
620 
622  // happens when no sina detected + menu entry is triggered via macro // @@@ would be nice to globally avoid callbacks for inactive menu entries
623 
624  aws->at_newline();
625  aws->label_length(0);
626  aws->label("SINA command\nError: Failed to find or identify sina version!");
627  aws->create_input_field(GA_AWAR_CMD, 20);
628 
629  return aws;
630  }
631 
632  aws->at_shift(10, 0);
633  aws->label_length(0);
634  aws->label("Show advanced options");
635  aws->create_toggle(GA_AWAR_ADVANCED);
636 
637  bool cbInstalled = false;
638  if (!cbInstalled) {
639  root->awar(GA_AWAR_ADVANCED)->add_callback(makeRootCallback(show_sina_window, alignData));
640  cbInstalled = true;
641  }
642 
643  aws->at_newline();
644  aws->at_shift(0, hgap);
645  int y_col2 = aws->get_at_yposition();
646  aws->label_length(15);
647  aws->create_toggle_field(GA_AWAR_TGT, "Align what?");
648  aws->insert_toggle("Current Species:", "C", 0);
649  aws->insert_toggle("Selected Species", "S", 1);
650  aws->insert_default_toggle("Marked Species", "M", 2);
651  aws->update_toggle_field();
652 
653  aws->at_shift(0, 3);
654  aws->create_input_field(AWAR_SPECIES_NAME, 20);
655 
656  aws->at_newline();
657  aws->at_shift(0, hgap);
658  aws->button_length(24);
659  if (used_sina_interface == ARB_5_99) {
660  aws->label("PT Server:");
661  }
662  else {
663  aws->label_length(20);
664  aws->label("PT Server\n"
665  "undefined => sina kmer");
666  }
668 
669  aws->label_length(0);
670 
671  if (gui_sina_interface == ARB_7_1) {
672  aws->at_newline();
673  aws->create_toggle_field(GA_AWAR_REFDB_MODE, "Reference database");
674  aws->insert_toggle("Explicit as ", "E", REF_EXPLICIT);
675  aws->insert_toggle("Last saved", "s", REF_LAST_SAVE);
676  aws->insert_default_toggle("Current", "C", REF_CURRENT);
677  aws->update_toggle_field();
678 
679  aws->at_shift(0, 3);
680  aws->callback(makeWindowCallback(sina_select_ref_db));
681  aws->create_autosize_button("selected", "selected", "s");
682 
683  aws->at_newline();
684  aws->create_input_field(GA_AWAR_REFDB, 40);
685  }
686 
687  aws->at_newline();
688  aws->label("Overhang placement");
689  aws->create_option_menu(GA_AWAR_OVERHANG);
690  aws->insert_option("keep attached", NULp, "attach");
691  aws->insert_option("move to edge", NULp, "edge");
692  aws->insert_option("remove", NULp, "remove");
693  aws->update_option_menu();
694 
695  aws->at_newline();
696  aws->label("Handling of unmappable insertions");
697  aws->create_option_menu(GA_AWAR_INSERT);
698  aws->insert_option("Shift surrounding bases", NULp, "shift");
699  aws->insert_option("Forbid during DP alignment", NULp, "forbid");
700  aws->insert_option("Delete bases", NULp, "remove");
701  aws->update_option_menu();
702 
703  int x_col2 = aws->get_at_xposition();
704 
705  aws->at_newline();
706  aws->label("Character Case");
707  aws->create_option_menu(GA_AWAR_LOWERCASE);
708  aws->insert_option("Do not modify", NULp, "original");
709  aws->insert_option("Show unaligned bases as lower case", NULp, "unaligned");
710  aws->insert_option("Uppercase all", NULp, "none");
711  aws->update_option_menu();
712 
713  aws->at_newline();
714  aws->label("Family conservation weight (0-1)");
715  aws->create_input_field(GA_AWAR_WEIGHT, 3);
716 
717  aws->at_newline();
718  aws->label("Size of full-length sequences");
719  aws->create_input_field(GA_AWAR_FULL_MINLEN, 5);
720 
721  aws->at_newline();
722  aws->label_length(17);
723  aws->label("Protection Level");
724  aws->create_option_menu(GA_AWAR_PROTECTION);
725  aws->insert_option("0", NULp, 0);
726  aws->insert_option("1", NULp, 1);
727  aws->insert_option("2", NULp, 2);
728  aws->insert_option("3", NULp, 3);
729  aws->insert_option("4", NULp, 4);
730  aws->insert_option("5", NULp, 5);
731  aws->insert_option("6", NULp, 6);
732  aws->update_option_menu();
733 
734  aws->at_newline();
735 
736  aws->label_length(21);
737  aws->label("Show changed sections");
738  aws->create_toggle(GA_AWAR_SHOW_DIFF);
739  aws->label_length(11);
740  aws->label("color bases");
741  aws->create_toggle(GA_AWAR_COLOR);
742 
743  aws->at_newline();
744  aws->label_length(21);
745  aws->label("Show statistics");
746  aws->create_toggle(GA_AWAR_SHOW_DIST);
747 
748  aws->at_newline();
749 
750  int startx, starty; aws->get_at_position(&startx, &starty);
751 
752  aws->button_length(12);
753  aws->at(closex, starty);
754  aws->callback(makeWindowCallback(sina_start, alignData));
755  aws->highlight();
756  aws->create_button("Start", "Start", "S");
757 
758  aws->at(closex2+200, starty-10);
759  AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "sina", sina_config_mapping);
760 
761  if (adv) {
762  aws->at(x_col2, y_col2);
763  aws->auto_space(5, 5); // resets position for at_newline
764 
765  aws->label_length(0);
766  aws->label("Pos. Var.:");
767  awt_create_SAI_selection_button(alignData->gb_main, aws, GA_AWAR_SAI, makeSaiSelectionlistFilterCallback(filter_posvar_SAI_for_ali, alignData->alignment_name.c_str()));
768 
769  aws->at_newline();
770  aws->label("Field used for automatic\nfilter selection");
771  aws->create_input_field(GA_AWAR_AUTOFILTER, 20);
772 
773  aws->at_newline();
774  aws->label("Turn check"); aws->create_toggle(GA_AWAR_TURN_CHECK);
775  aws->label("Realign"); aws->create_toggle(GA_AWAR_REALIGN);
776 
777  aws->at_newline();
778  aws->at_shift(0, hgap);
779 
780  aws->label("Gap insertion/extension penalties");
781  aws->create_input_field(GA_AWAR_GAP_PEN, 5);
782  aws->create_input_field(GA_AWAR_GAP_EXT, 5);
783 
784  aws->at_newline();
785  aws->label("Match score");
786  aws->create_input_field(GA_AWAR_MATCH_SCORE, 3);
787  aws->label("Mismatch score");
788  aws->create_input_field(GA_AWAR_MISMATCH_SCORE, 3);
789 
790  aws->at_newline();
791  aws->label("Family search min/min_score/max");
792  aws->create_input_field(GA_AWAR_FS_MIN, 3);
793  aws->create_input_field(GA_AWAR_FS_MSC, 3);
794  aws->create_input_field(GA_AWAR_FS_MAX, 3);
795 
796  aws->at_newline();
797  aws->label("Minimal number of full length sequences");
798  aws->create_input_field(GA_AWAR_MIN_FULL, 3);
799 
800  aws->at_newline();
801  aws->label("Family search oligo length / mismatches");
802  aws->create_input_field(GA_AWAR_KMER_LEN, 3);
803  aws->create_input_field(GA_AWAR_KMER_MM, 3);
804 
805  aws->at_newline();
806  aws->label("Minimal reference sequence length");
807  aws->create_input_field(GA_AWAR_MIN_LEN, 5);
808 
809  aws->at_newline();
810  aws->label("Alignment bounds: start");
811  aws->create_input_field(GA_AWAR_GENE_START, 6);
812  aws->label("end");
813  aws->create_input_field(GA_AWAR_GENE_END, 6);
814 
815  aws->at_newline();
816  aws->label("Number of references required to touch bounds");
817  aws->create_input_field(GA_AWAR_FS_COVER_GENE, 3);
818 
819  aws->at_newline();
820  aws->label("Save used references in 'used_rels'");
821  aws->create_toggle(GA_AWAR_USED_RELS);
822 
823  aws->at_newline();
824  aws->label("Store highest identity in 'align_ident_slv'");
825  aws->create_toggle(GA_AWAR_CALC_IDENTITY);
826 
827  aws->at_newline();
828  aws->label("Disable fast search");
829  aws->create_toggle(GA_AWAR_KMER_NOFAST);
830 
831  aws->at_newline();
832  aws->label("Score search results by absolute oligo match count");
833  aws->create_toggle(GA_AWAR_KMER_NOREL);
834 
835  if (gui_sina_interface == ARB_7_1) {
836  aws->at_newline();
837  aws->label("Suppress warnings about missing 'start' field");
838  aws->create_toggle(GA_AWAR_NOWARN_START);
839  }
840 
841  aws->at_newline();
842  aws->label("SINA command");
843  aws->create_input_field(GA_AWAR_CMD, 20);
844  }
845 
846  int winx, winy; aws->get_window_size(winx, winy);
847 
848  aws->button_length(12);
849  aws->at(winx-closex2+5, closey);
850  aws->callback(makeHelpCallback("sina_main.hlp"));
851  aws->create_button("HELP", "HELP");
852 
853  return aws;
854 }
855 
856 void show_sina_window(UNFIXED, const AlignDataAccess *alignData) {
857  AW_root *root = AW_root::SINGLETON;
858 
859  static AW_window_simple *ga_aws = NULp;
860  static AW_window_simple *ga_aws_adv = NULp;
861 
862  if (root->awar(GA_AWAR_ADVANCED)->read_int()) {
863  if (!ga_aws_adv) ga_aws_adv = new_sina_simple(root, alignData, true);
864  ga_aws_adv->show();
865 
866  if (ga_aws) ga_aws->hide();
867  }
868  else {
869  if (!ga_aws) ga_aws = new_sina_simple(root, alignData, false);
870  ga_aws->show();
871 
872  if (ga_aws_adv) ga_aws_adv->hide();
873  }
874 
875  static bool refdb_mode_refreshed = false;
876  if (!refdb_mode_refreshed) {
877  AW_awar *awar_mode = root->awar(GA_AWAR_REFDB_MODE);
878  if (awar_mode->read_int() != REF_EXPLICIT) awar_mode->touch(); // trigger callback
879  refdb_mode_refreshed = true;
880  }
881 }
882 
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2528
#define GA_AWAR_GENE_START
SinaArbInterfaceVersion version
const char * GB_ERROR
Definition: arb_core.h:25
const char * stream2static(const std::stringstream &str)
AW_bitset AW_active
Definition: aw_base.hxx:45
string result
GB_TYPES type
#define GA_AWAR_FS_MAX
GB_ERROR GB_commit_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2551
void GB_remove_on_exit(const char *filename)
Definition: adsocket.cxx:1258
#define AWAR_SAVED_DB_PATH
GBDATA * GBT_first_marked_species(GBDATA *gb_main)
Definition: aditem.cxx:113
static char * filter_posvar_SAI_for_ali(GBDATA *gb_extended, const char *ali_name)
return string(buffer, length)
#define GA_AWAR_SHOW_DIST
#define GA_AWAR_COLOR
#define GA_AWAR_OVERHANG
GBDATA * GB_find(GBDATA *gbd, const char *key, GB_SEARCH_TYPE gbs)
Definition: adquery.cxx:295
AW_window * awt_create_load_box(AW_root *aw_root, const char *action, const char *what, const char *default_directory, const char *file_extension, char **set_file_name_awar, const WindowCallback &ok_cb, const WindowCallback &close_cb, const char *close_button_text)
void ARB_warn_about_unwanted_chars(const char *path, const char *path_description)
Definition: arb_misc.cxx:150
Aligner_get_first_selected_species get_first_selected_species
#define GA_AWAR_LOWERCASE
#define GA_AWAR_TURN_CHECK
void AWT_insert_config_manager(AW_window *aww, AW_default default_file_, const char *id, const StoreConfigCallback &store_cb, const RestoreConfigCallback &load_or_reset_cb, const char *macro_id, const AWT_predefined_config *predef)
GB_ERROR arb_look_and_start_server(long magic_number, const char *arb_tcp_env)
long read_int() const
Definition: AW_awar.cxx:184
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
#define GA_AWAR_FS_MSC
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
#define GA_AWAR_WEIGHT
std::string alignment_name
#define GA_AWAR_CMD
static AW_window_simple * new_sina_simple(AW_root *root, const AlignDataAccess *alignData, bool adv)
void cat(const char *from)
Definition: arb_strbuf.h:199
#define EXIT_SUCCESS
Definition: arb_a2ps.c:154
Aligner_get_next_selected_species get_next_selected_species
SinaArbInterfaceVersion
void awt_create_SAI_selection_button(GBDATA *gb_main, AW_window *aws, const char *varname, const SaiSelectionlistFilterCallback &fcb)
#define GA_AWAR_MIN_FULL
#define GA_AWAR_REALIGN
void activate()
Definition: aw_window.hxx:365
#define GA_AWAR_SHOW_DIFF
static AW_window * create_ref_db_selection_window(AW_root *aw_root)
#define GA_AWAR_MISMATCH_SCORE
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
struct Unfixed_cb_parameter * UNFIXED
Definition: cb_base.h:15
#define GA_AWAR_KMER_MM
const char * empty_as_none(const char *sainame)
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
void putlong(long l)
Definition: arb_strbuf.h:240
char * ARB_executable(const char *exe_name, const char *path)
Definition: arb_misc.cxx:107
#define ga_assert(cond)
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
#define GA_AWAR_NOWARN_START
static AW_root * SINGLETON
Definition: aw_root.hxx:102
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
#define AWAR_PT_SERVER
const char * GBS_read_arb_tcp(const char *env)
Definition: adtcp.cxx:325
#define GA_AWAR_KMER_NOFAST
#define GA_AWAR_INSERT
#define GA_AWAR_FULL_MINLEN
void show_sina_window(UNFIXED, const AlignDataAccess *alignData)
AW_awar * awar_float(const char *var_name, float default_value=0.0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:560
#define GA_AWAR_REFDB_SELECT
void putfloat(float f)
Definition: arb_strbuf.h:241
#define GA_AWAR_REFDB_MODE
void touch()
Definition: AW_awar.cxx:207
#define GA_AWAR_CALC_IDENTITY
FILE * GB_fopen_tempfile(const char *filename, const char *fmode, char **res_fullname)
Definition: adsocket.cxx:1176
static GB_ERROR detect_sina_version(AW_root *awr)
#define GA_AWAR_GAP_EXT
GBDATA * GBT_next_marked_species(GBDATA *gb_species)
Definition: aditem.cxx:116
#define GA_AWAR_ADVANCED
#define AWAR_SPECIES_NAME
#define GA_AWAR_KMER_NOREL
static AWT_config_mapping_def sina_config_mapping[]
NOT4PERL GB_ERROR GB_xcmd(const char *cmd, XCMD_TYPE exectype) __ATTR__USERESULT_TODO
Definition: adsocket.cxx:906
char * read_string() const
Definition: AW_awar.cxx:198
static void newRefDbSelected_cb(AW_root *root)
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
static sina_arb_interface_def supported_sina_versions[]
Definition: arbdb.h:86
static void accept_selected_ref_db(AW_window *aww, const char *const *awar_filename)
#define GA_AWAR_THREADS
#define GA_AWAR_FS_MIN
#define EXIT_FAILURE
Definition: arb_a2ps.c:157
void awt_create_PTSERVER_selection_button(AW_window *aws, const char *varname)
float read_float() const
Definition: AW_awar.cxx:177
GB_CSTR GB_getenv(const char *env)
Definition: adsocket.cxx:709
#define AISC_MAGIC_NUMBER
Definition: client_privat.h:51
char * GB_unique_filename(const char *name_prefix, const char *suffix)
Definition: adsocket.cxx:1233
#define GA_AWAR_PROTECTION
#define GA_AWAR_QSIZE
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
char ARB_path_contains_unwanted_chars(const char *path)
Definition: arb_misc.cxx:143
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:909
const SinaArbInterfaceVersion NO_INTERFACE
const char * GBS_static_string(const char *str)
Definition: arb_msg.cxx:212
#define GA_AWAR_KMER_LEN
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
void hide()
Definition: AW_window.cxx:1835
#define GA_AWAR_REFDB
AW_root * get_root()
Definition: aw_window.hxx:359
#define GA_AWAR_GAP_PEN
#define NULp
Definition: cxxforward.h:116
bool GB_is_readablefile(const char *filename)
Definition: arb_file.cxx:172
static const char * get_interface_id(SinaArbInterfaceVersion version)
GB_ERROR write_string(const char *aw_string)
static void refDbModeChanged_cb(AW_root *root)
const char * get_data() const
Definition: arb_strbuf.h:120
#define GA_AWAR_AUTOFILTER
static SinaArbInterfaceVersion used_sina_interface
#define GA_AWAR_TGT
#define GA_AWAR_SAI
#define GA_AWAR_USED_RELS
static SinaArbInterfaceVersion gui_sina_interface
#define GA_AWAR_GENE_END
#define GA_AWAR_MATCH_SCORE
GB_CSTR GB_read_char_pntr(GBDATA *gbd)
Definition: arbdb.cxx:904
GBDATA * gb_main
Definition: adname.cxx:32
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
void create_sina_variables(AW_root *root, AW_default db1)
static void sina_select_ref_db(AW_window *aww)
#define GA_AWAR_MIN_LEN
static void sina_cmd_changed_cb(AW_root *awr)
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
GB_ERROR write_int(long aw_int)
void cat_sQuoted(const char *from)
Definition: arb_strbuf.h:251
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
#define GA_AWAR_FS_COVER_GENE
static void sina_start(AW_window *window, const AlignDataAccess *data_access)
AW_active sina_mask(AW_root *awr)