ARB
MG_species.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : MG_species.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "merge.hxx"
12 #include "MG_adapt_ali.hxx"
13 
14 #include <AW_rename.hxx>
15 #include <db_query.h>
16 #include <db_scanner.hxx>
17 #include <item_sel_list.h>
18 
19 #include <xfergui.h>
20 #include <xferset.h>
21 
22 #include <aw_awars.hxx>
23 #include <aw_msg.hxx>
24 #include <arb_progress.h>
25 #include <aw_root.hxx>
26 #include <aw_question.hxx>
27 
28 #include <arb_str.h>
29 #include <arb_strbuf.h>
30 #include <arb_global_defs.h>
31 #include <config_manager.hxx>
32 
33 
34 #define AWAR_SPECIES_SRC AWAR_MERGE_TMP_SRC "name"
35 #define AWAR_FIELD_SRC AWAR_MERGE_TMP_SRC "field"
36 #define AWAR_TAG_SRC AWAR_MERGE_TMP_SRC "tag"
37 
38 #define AWAR_SPECIES_DST AWAR_MERGE_TMP_DST "name"
39 #define AWAR_FIELD_DST AWAR_MERGE_TMP_DST "field"
40 #define AWAR_TAG_DST AWAR_MERGE_TMP_DST "tag"
41 
42 #define AWAR_TAG_DEL AWAR_MERGE_TMP "tagdel"
43 #define AWAR_APPEND AWAR_MERGE_TMP "append"
44 
45 #define AWAR_SPECIES_XFER_TYPE AWAR_MERGE_SAV "xferType"
46 #define AWAR_SPECIES_XFER_SCOPE AWAR_MERGE_SAV "xferScope"
47 #define AWAR_SPECIES_XFER_FTS AWAR_MERGE_SAV "fts"
48 
51 
54  SXT_SINGLE_FIELD, // (skips alignment data)
55  SXT_USING_FTS, // field transfer set
56  SXT_USING_FTS_SKIP_ALI, // field transfer set (skips alignment data)
57 };
58 
62 };
63 
65 
66 void MG_create_species_awars(AW_root *aw_root, AW_default aw_def) {
67  aw_root->awar_string(AWAR_SPECIES_SRC, "", aw_def);
68  aw_root->awar_string(AWAR_SPECIES_DST, "", aw_def);
69 
70  aw_root->awar_string(AWAR_FIELD_SRC, NO_FIELD_SELECTED, aw_def);
71  aw_root->awar_string(AWAR_FIELD_DST, NO_FIELD_SELECTED, aw_def);
72 
73  aw_root->awar_int(AWAR_APPEND, 0, aw_def);
74 
77 
78  aw_root->awar_string(AWAR_SPECIES_XFER_FTS, "", aw_def);
79 }
80 
81 static void MG_map_species(AW_root *aw_root, DbSel db) {
82  GBDATA *gb_main = get_gb_main(db);
83  const char *awar_name = db == SRC_DB ? AWAR_SPECIES_SRC : AWAR_SPECIES_DST;
84  DbScanner *scanner = db == SRC_DB ? scanner_src : scanner_dst;
85 
86  GB_transaction ta(gb_main);
87  char *selected_species = aw_root->awar(awar_name)->read_string();
88  GBDATA *gb_species = GBT_find_species(gb_main, selected_species);
89  if (gb_species) {
90  scanner->Map(gb_species, awar_name); // @@@ why is awar_name passed here? (normally a changekey-path is used)
91  // @@@ undocumented feature in DbScanner or bug?
92  }
93  free(selected_species);
94 }
95 
96 static GB_ERROR MG_transfer_fields_info(char *fieldname = NULp) {
99 
100  if (!gb_key_data) error = GB_await_error();
101  else {
103  else {
104  for (GBDATA *gb_key = GB_entry(gb_key_data, CHANGEKEY);
105  gb_key && !error;
106  gb_key = GB_nextEntry(gb_key))
107  {
108  GBDATA *gb_key_name = GB_entry(gb_key, CHANGEKEY_NAME);
109  if (gb_key_name) {
110  GBDATA *gb_key_type = GB_entry(gb_key, CHANGEKEY_TYPE);
111  if (gb_key_type) {
112  char *name = GB_read_string(gb_key_name);
113 
114  if (!fieldname || strcmp(fieldname, name) == 0) {
115  error = GBT_add_new_species_changekey(GLOBAL_gb_dst, name, GB_TYPES(GB_read_int(gb_key_type)));
116  }
117  free(name);
118  }
119  }
120  }
121  }
122  }
123  return error;
124 }
125 
127  GBDATA *gb_src_species, GBDATA *gb_dst_species_data,
128  bool src_is_genome, bool dst_is_genome,
129  GB_HASH *source_organism_hash, GB_HASH *dest_species_hash,
130  GB_HASH *error_suppressor)
131 {
132  // copies species 'gb_src_species' from source to destination DB.
133  //
134  // 'source_organism_hash' may be NULp, otherwise it's used to search for source organisms (when merging from genome DB)
135  // 'dest_species_hash' may be NULp, otherwise created species is stored there
136 
137  mg_assert(gb_src_species);
138 
139  GB_ERROR error = NULp;
140  const char *src_name = GBT_get_name(gb_src_species);
141  bool transfer_fields = false;
142 
143  if (!src_name) {
144  error = "refused to transfer unnamed species";
145  }
146  else {
147  if (src_is_genome) {
148  if (dst_is_genome) { // genome -> genome
149  if (GEN_is_pseudo_gene_species(gb_src_species)) {
150  const char *origin = GEN_origin_organism(gb_src_species);
151  GBDATA *dest_organism = dest_species_hash
152  ? (GBDATA*)GBS_read_hash(dest_species_hash, origin)
153  : GEN_find_organism(GLOBAL_gb_dst, origin);
154 
155  if (dest_organism) transfer_fields = true;
156  else {
157  error = GBS_global_string("Destination DB does not contain '%s's origin-organism '%s'",
158  src_name, origin);
159  }
160  }
161  // else: merge organism ok
162  }
163  else { // genome -> non-genome
164  if (GEN_is_pseudo_gene_species(gb_src_species)) transfer_fields = true;
165  else {
166  error = GBS_global_string("You can't merge organisms (%s) into a non-genome DB.\n"
167  "Only pseudo-species are possible", src_name);
168  }
169  }
170  }
171  else {
172  if (dst_is_genome) { // non-genome -> genome
173  error = GBS_global_string("You can't merge non-genome species (%s) into a genome DB", src_name);
174  }
175  // else: non-genome -> non-genome ok
176  }
177  }
178 
179  GBDATA *gb_dst_species = NULp;
180  if (!error) {
181  gb_dst_species = dest_species_hash
182  ? (GBDATA*)GBS_read_hash(dest_species_hash, src_name)
183  : GBT_find_species_rel_species_data(gb_dst_species_data, src_name);
184 
185  if (gb_dst_species) error = GB_delete(gb_dst_species);
186  }
187  if (!error) {
188  gb_dst_species = GB_create_container(gb_dst_species_data, "species");
189  if (!gb_dst_species) error = GB_await_error();
190  }
191  if (!error) error = GB_copy_dropProtectMarksAndTempstate(gb_dst_species, gb_src_species);
192  if (!error && transfer_fields) {
193  mg_assert(src_is_genome);
194  error = MG_export_fields(aw_root, gb_src_species, gb_dst_species, error_suppressor, source_organism_hash);
195  }
196  if (!error) GB_write_flag(gb_dst_species, 1);
197  if (!error) error = MG_adaptAllCopiedAlignments(remap, gb_src_species, gb_dst_species);
198  if (!error && dest_species_hash) GBS_write_hash(dest_species_hash, src_name, (long)gb_dst_species);
199 
200  return error;
201 }
202 
203 static const char *get_reference_species_names(AW_root *awr) {
205 }
206 static bool adaption_enabled(AW_root *awr) {
207  return awr->awar(AWAR_REMAP_ENABLE)->read_int() != 0;
208 }
209 
211  if (MG_copy_and_check_alignments() != 0) return;
212 
213  AW_root *aw_root = aww->get_root();
214  char *src_name = aw_root->awar(AWAR_SPECIES_SRC)->read_string();
215  GB_ERROR error = NULp;
216 
217  if (!src_name || !src_name[0]) {
218  error = "Please select a species in the left list";
219  }
220  else {
221  arb_progress progress("Transferring selected species");
222 
224  if (!error) error = GB_begin_transaction(GLOBAL_gb_dst);
225 
226  if (!error) {
228 
229  GBDATA *gb_src_species_data = GBT_get_species_data(GLOBAL_gb_src);
230  GBDATA *gb_dst_species_data = GBT_get_species_data(GLOBAL_gb_dst);
231 
232  bool src_is_genome = GEN_is_genome_db(GLOBAL_gb_src, -1);
233  bool dst_is_genome = GEN_is_genome_db(GLOBAL_gb_dst, -1);
234 
235  GBDATA *gb_src_species = GBT_find_species_rel_species_data(gb_src_species_data, src_name);
236  if (!gb_src_species) {
237  error = GBS_global_string("Could not find species '%s' in source database", src_name);
238  }
239  else {
240  error = MG_transfer_one_species(aw_root, rm,
241  gb_src_species, gb_dst_species_data,
242  src_is_genome, dst_is_genome,
243  NULp, NULp,
244  NULp);
245  }
246  }
247 
248  if (!error) error = MG_transfer_fields_info();
249 
250  error = GB_end_transaction(GLOBAL_gb_src, error);
251  error = GB_end_transaction(GLOBAL_gb_dst, error);
252  }
253 
254  if (error) aw_message(error);
255 }
256 
258  if (MG_copy_and_check_alignments() != 0) return;
259 
260  GB_ERROR error = NULp;
263 
264  bool src_is_genome = GEN_is_genome_db(GLOBAL_gb_src, -1);
265  bool dst_is_genome = GEN_is_genome_db(GLOBAL_gb_dst, -1);
266 
267  GB_HASH *error_suppressor = GBS_create_hash(50, GB_IGNORE_CASE);
268  GB_HASH *dest_species_hash = GBT_create_species_hash(GLOBAL_gb_dst);
269  GB_HASH *source_organism_hash = src_is_genome ? GBT_create_organism_hash(GLOBAL_gb_src) : NULp;
270 
271  AW_root *aw_root = aww->get_root();
273 
274  GBDATA *gb_src_species;
275  arb_progress progress("Transferring listed species", mg_count_queried(GLOBAL_gb_src));
276 
277  for (gb_src_species = GBT_first_species(GLOBAL_gb_src);
278  gb_src_species;
279  gb_src_species = GBT_next_species(gb_src_species))
280  {
281  if (IS_QUERIED_SPECIES(gb_src_species)) {
282  GBDATA *gb_dst_species_data = GBT_get_species_data(GLOBAL_gb_dst);
283 
284  error = MG_transfer_one_species(aw_root, rm,
285  gb_src_species, gb_dst_species_data,
286  src_is_genome, dst_is_genome,
287  source_organism_hash, dest_species_hash,
288  error_suppressor);
289 
290  progress.inc_and_check_user_abort(error);
291  }
292  }
293 
294  GBS_free_hash(dest_species_hash);
295  if (source_organism_hash) GBS_free_hash(source_organism_hash);
296  GBS_free_hash(error_suppressor);
297 
298  if (!error) error = MG_transfer_fields_info();
299 
300  error = GB_end_transaction(GLOBAL_gb_src, error);
302 }
303 
304 static GB_ERROR transfer_single_field(GBDATA *const gb_src_species, GBDATA *const gb_dst_species, const char *const field, GBDATA *const gb_src_field, const bool append, const bool transfer_of_alignment, const MG_remaps& rm) {
305  GBDATA *gb_dst_field = GB_search(gb_dst_species, field, GB_FIND);
306  GB_TYPES src_type = GB_read_type(gb_src_field);
307  GB_TYPES dst_type = gb_dst_field ? GB_read_type(gb_dst_field) : src_type;
308 
309  bool use_copy = true;
310  GB_ERROR error = NULp;
311 
312  if (append) {
313  if (src_type != GB_STRING || dst_type != GB_STRING) {
314  error = "You can use 'Append data' with text fields only!";
315  }
316  else if (gb_dst_field) { // append possible (otherwise use_copy!)
317  char *src_val = GB_read_string(gb_src_field);
318  char *dst_val = GB_read_string(gb_dst_field);
319 
320  if (!src_val || !dst_val) error = GB_await_error();
321  else {
322  if (!GBS_find_string(dst_val, src_val, 0)) { // do not append if dst_val contains src_val
323  error = GB_write_string(gb_dst_field, GBS_global_string("%s %s", dst_val, src_val));
324  if (!error) GB_write_flag(gb_dst_species, 1);
325  }
326  }
327 
328  free(src_val);
329  free(dst_val);
330 
331  use_copy = false;
332  }
333  }
334 
335  if (!error && use_copy) {
336  if (dst_type != src_type) error = "type mismatch"; // abort early (previously failed in call to MG_transfer_fields_info below)
337  if (!error && src_type == GB_DB && gb_dst_field) {
338  // if type is container -> delete before copy
339  // (otherwise it would generate a mix of both containers; if wanted provide optionally)
340  error = GB_delete(gb_dst_field);
341  gb_dst_field = NULp; // trigger recreation+copy
342  }
343  if (!error && !gb_dst_field) { // create missing target field (otherwise simply overwrite)
344  gb_dst_field = GB_search(gb_dst_species, field, src_type);
345  if (!gb_dst_field) error = GB_await_error(); // failed to create?
346  }
347  if (!error) error = GB_copy_dropProtectMarksAndTempstate(gb_dst_field, gb_src_field); // [Note: if transfer_of_alignment -> copies 'data' field of one alignment]
348  if (!error && transfer_of_alignment) error = MG_adaptAllCopiedAlignments(rm, gb_src_species, gb_dst_species); // [Note: adapts all copied alignments, if adapt toggle is checked]
349  if (!error) GB_write_flag(gb_dst_species, 1);
350  }
351  return error;
352 }
353 
354 inline bool fieldContainsAlignment(const char *field) {
355  return GBS_string_matches(field, "ali_*", GB_MIND_CASE);
356 }
357 
359  if (MG_copy_and_check_alignments() != 0) return;
360 
361  AW_root *aw_root = aww->get_root();
362  char *field = aw_root->awar(AWAR_FIELD_SRC)->read_string();
363  const bool append = aw_root->awar(AWAR_APPEND)->read_int();
364  GB_ERROR error = NULp;
365 
366  if (strcmp(field, NO_FIELD_SELECTED) == 0) {
367  error = "Please select the field you like to transfer";
368  }
369  else if (strcmp(field, "name") == 0) {
370  error = "Transferring the 'name' field is forbidden";
371  }
372  else {
373  const bool transfer_of_alignment = fieldContainsAlignment(field);
374 
375  if (transfer_of_alignment && append) {
376  error = "Appending alignment data is not permitted\n"
377  "(please refer to ARB_NT/Sequence/Concatenate.. to do so)";
378  }
379  else {
381  if (!error) error = GB_begin_transaction(GLOBAL_gb_dst);
382 
383  if (!error) {
384  arb_progress progress("Transferring fields of listed", mg_count_queried(GLOBAL_gb_src));
385 
386  MG_remaps rm(GLOBAL_gb_src, GLOBAL_gb_dst, adaption_enabled(aw_root), get_reference_species_names(aw_root)); // @@@ unused if transfer_of_alignment == false
387 
388  GBDATA *gb_dest_species_data = GBT_get_species_data(GLOBAL_gb_dst);
389  if (!gb_dest_species_data) error = GB_await_error();
390 
391  for (GBDATA *gb_src_species = GBT_first_species(GLOBAL_gb_src);
392  gb_src_species && !error;
393  gb_src_species = GBT_next_species(gb_src_species))
394  {
395  if (IS_QUERIED_SPECIES(gb_src_species)) {
396  const char *src_name = GBT_get_name(gb_src_species);
397  if (src_name) {
398  GBDATA *gb_dst_species = GB_find_string(gb_dest_species_data, "name", src_name, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
399 
400  if (!gb_dst_species) {
401  gb_dst_species = GB_create_container(gb_dest_species_data, "species");
402  if (!gb_dst_species) error = GB_await_error();
403  else error = GBT_write_string(gb_dst_species, "name", src_name);
404  }
405  else {
406  gb_dst_species = GB_get_father(gb_dst_species);
407  }
408 
409  if (!error) {
410  // @@@ DRY vs inner part of body of transfer_field_of_selected_cb .@DRY_TRANSFER_FIELD
411  GBDATA *gb_src_field = GB_search(gb_src_species, field, GB_FIND);
412 
413  if (gb_src_field) {
414  error = transfer_single_field(gb_src_species, gb_dst_species, field, gb_src_field, append, transfer_of_alignment, rm);
415  }
416  }
417  if (error) error = GBS_global_string("%s (species=%s)", error, src_name); // mention name of species in error message
418  }
419  else {
420  error = "refusing to transfer from unnamed species";
421  }
422 
423  progress.inc_and_check_user_abort(error);
424  }
425  }
426  }
427 
428  if (!error) error = MG_transfer_fields_info(field);
429 
430  error = GB_end_transaction(GLOBAL_gb_src, error);
431  error = GB_end_transaction(GLOBAL_gb_dst, error);
432  }
433  }
434 
435  if (error) aw_message(error);
436  free(field);
437 }
438 
440  if (MG_copy_and_check_alignments() != 0) return;
441 
442  AW_root *aw_root = aww->get_root();
443  char *field = aw_root->awar(AWAR_FIELD_SRC)->read_string();
444  const bool append = false; // @@@ provide via GUI?
445  GB_ERROR error = NULp;
446 
447  if (strcmp(field, NO_FIELD_SELECTED) == 0) {
448  error = "Please select the field you like to transfer";
449  }
450  else if (strcmp(field, "name") == 0) {
451  error = "Transferring the 'name' field is forbidden";
452  }
453  else {
454  const bool transfer_of_alignment = fieldContainsAlignment(field);
455 
456  if (transfer_of_alignment && append) { // @@@ append always false (see above)
457  error = "Appending alignment data is not permitted\n"
458  "(please refer to ARB_NT/Sequence/Concatenate.. to do so)";
459  }
460  else {
462  if (!error) error = GB_begin_transaction(GLOBAL_gb_dst);
463 
464  if (!error) {
465  arb_progress progress("Cross copy field");
466 
467  MG_remaps rm(GLOBAL_gb_src, GLOBAL_gb_dst, adaption_enabled(aw_root), get_reference_species_names(aw_root)); // @@@ unused if transfer_of_alignment == false
468 
469  GBDATA *gb_src_species;
470  GBDATA *gb_dst_species;
471  {
472  char *src_name = aw_root->awar(AWAR_SPECIES_SRC)->read_string();
473  char *dst_name = aw_root->awar(AWAR_SPECIES_DST)->read_string();
474 
475  gb_src_species = GBT_find_species(GLOBAL_gb_src, src_name);
476  gb_dst_species = GBT_find_species(GLOBAL_gb_dst, dst_name);
477 
478  free(dst_name);
479  free(src_name);
480  }
481 
482  if (!gb_src_species) error = "Please select a species in left hitlist";
483  if (!gb_dst_species) error = "Please select a species in right hitlist";
484 
485  if (!error) {
486  // @@@ DRY vs loop-body of transfer_field_of_listed_cb .@DRY_TRANSFER_FIELD
487  GBDATA *gb_src_field = GB_search(gb_src_species, field, GB_FIND);
488  if (!gb_src_field) error = GBS_global_string("Source species has no field '%s'", field);
489 
490  if (!error) {
491  error = transfer_single_field(gb_src_species, gb_dst_species, field, gb_src_field, append, transfer_of_alignment, rm);
492  }
493  }
494  }
495  if (!error) error = MG_transfer_fields_info(field);
496 
497  error = GB_end_transaction(GLOBAL_gb_src, error);
498  error = GB_end_transaction(GLOBAL_gb_dst, error);
499  }
500  }
501 
502  if (error) aw_message(error);
503 
504  free(field);
505 }
506 
508  static AW_window *aww[2] = { NULp, NULp }; // its ok to store windows here (not handled by popper())
509 
510  if (!aww[scope]) {
512  AW_window_simple *aws = new AW_window_simple;
513 
514  bool listed = scope == SXS_LISTED_SPECIES;
515  mg_assert(implicated(!listed, scope == SXS_SELECTED_SPECIES));
516 
517  if (listed) aws->init(aw_root, "MERGE_XFER_FIELD_OF_LISTED", "Transfer field of listed");
518  else aws->init(aw_root, "MERGE_XFER_SINGLE_FIELD", "Transfer field of selected");
519 
520  aws->load_xfig("merge/mg_transfield.fig");
521  aws->button_length(10);
522 
523  aws->callback(AW_POPDOWN);
524  aws->at("close");
525  aws->create_button("CLOSE", "CLOSE", "C");
526 
527  aws->at("help");
528  aws->callback(makeHelpCallback(listed ? "mg_xfer_field_of_listed.hlp" : "mg_xfer_field_of_sel.hlp"));
529  aws->create_button("HELP", "HELP");
530 
531  if (listed) {
532  aws->at("append");
533  aws->label("Append data?");
534  aws->create_toggle(AWAR_APPEND);
535  }
536 
537  long typeFilter = listed ? FIELD_FILTER_ANY_FIELD : FIELD_UNFILTERED;
538  create_itemfield_selection_button(aws, FieldSelDef(AWAR_FIELD_SRC, GLOBAL_gb_src, SPECIES_get_selector(), typeFilter, "source/target field"), "scandb");
539 
540  aws->at("go");
542  aws->create_button("GO", "GO");
543 
544  aww[scope] = aws;
545  }
546  aww[scope]->activate();
547 }
548 
550  GB_transaction ta_merge(GLOBAL_gb_src);
552 
553  if (!error) {
554  AW_root *awr = aww->get_root();
555 
556  char *src_field = awr->awar(AWAR_FIELD_SRC)->read_string();
557  char *dst_field = awr->awar(AWAR_FIELD_DST)->read_string();
558 
559  if (strcmp(src_field, NO_FIELD_SELECTED) == 0 ||
560  strcmp(dst_field, NO_FIELD_SELECTED) == 0)
561  {
562  error = "Please select source- and target-fields.";
563  }
564 
565  if (!error) {
566  char *src_tag = awr->awar(AWAR_TAG_SRC)->read_string();
567  char *dst_tag = awr->awar(AWAR_TAG_DST)->read_string();
568  char *del_tag = awr->awar(AWAR_TAG_DEL)->read_string();
569 
570  arb_progress progress("Merging tagged fields", mg_count_queried(GLOBAL_gb_src));
571 
572  GBDATA *gb_dest_species_data = GBT_get_species_data(GLOBAL_gb_dst);
573  if (!gb_dest_species_data) error = GB_await_error();
574  else {
575  for (GBDATA *gb_src_species = GBT_first_species(GLOBAL_gb_src);
576  gb_src_species && !error;
577  gb_src_species = GBT_next_species(gb_src_species))
578  {
579  if (IS_QUERIED_SPECIES(gb_src_species)) {
580  char *name = GBT_read_string(gb_src_species, "name");
581  if (!name) error = GB_await_error();
582  else {
583  GBDATA *gb_dst_species = GBT_find_or_create_species_rel_species_data(gb_dest_species_data, name, true);
584  if (!gb_dst_species) error = GB_await_error();
585  else {
586  char *src_val = GBT_readOrCreate_string(gb_src_species, src_field, "");
587  char *dst_val = GBT_readOrCreate_string(gb_dst_species, dst_field, "");
588 
589  if (!src_val || !dst_val) error = GB_await_error();
590  else {
591  char *sum = GBS_merge_tagged_strings(src_val, src_tag, del_tag,
592  dst_val, dst_tag, del_tag);
593 
594  if (!sum) error = GB_await_error();
595  else error = GBT_write_string(gb_dst_species, dst_field, sum);
596  free(sum);
597  }
598  free(dst_val);
599  free(src_val);
600  }
601  }
602  free(name);
603  progress.inc_and_check_user_abort(error);
604  }
605  }
606  }
607 
608  if (error) progress.done();
609 
610  free(del_tag);
611  free(dst_tag);
612  free(src_tag);
613  }
614  free(dst_field);
615  free(src_field);
616  }
618 }
619 
621  static AW_window_simple *aws = NULp;
622  if (aws) return aws;
623 
625 
626  aw_root->awar_string(AWAR_TAG_SRC, "S");
627  aw_root->awar_string(AWAR_TAG_DST, "D");
628 
629  aw_root->awar_string(AWAR_TAG_DEL, "S*");
630 
631  aws = new AW_window_simple;
632  aws->init(aw_root, "MERGE_TAGGED_FIELD", "Merge tagged field");
633  aws->load_xfig("merge/mg_mergetaggedfield.fig");
634  aws->button_length(13);
635 
636  aws->callback(AW_POPDOWN);
637  aws->at("close");
638  aws->create_button("CLOSE", "CLOSE", "C");
639 
640  aws->at("go");
641  aws->callback(MG_merge_tagged_field_cb);
642  aws->create_button("GO", "GO");
643 
644  aws->at("help");
645  aws->callback(makeHelpCallback("mergetaggedfield.hlp"));
646  aws->create_button("HELP", "HELP");
647 
648  aws->at("tag1"); aws->create_input_field(AWAR_TAG_SRC, 5);
649  aws->at("tag2"); aws->create_input_field(AWAR_TAG_DST, 5);
650 
651  aws->at("del1"); aws->create_input_field(AWAR_TAG_DEL, 5);
652 
655 
656  return aws;
657 }
658 
659 static GB_ERROR MG_equal_alignments(bool autoselect_equal_alignment_name) {
661  ConstStrArray S_alignment_names;
662  ConstStrArray D_alignment_names;
663  GBT_get_alignment_names(S_alignment_names, GLOBAL_gb_src);
664  GBT_get_alignment_names(D_alignment_names, GLOBAL_gb_dst);
665 
666  GB_ERROR error = NULp;
667  if (!S_alignment_names[0]) {
668  error = GB_export_error("No source sequences found");
669  }
670  else {
671  char *src_type = GBT_get_alignment_type_string(GLOBAL_gb_src, S_alignment_names[0]);
672  const char *dest = NULp;
673 
674  for (int d = D_alignment_names.size()-1; d>0; --d) {
675  char *dst_type = GBT_get_alignment_type_string(GLOBAL_gb_dst, D_alignment_names[d]);
676  if (strcmp(src_type, dst_type) != 0) D_alignment_names.remove(d--);
677  free(dst_type);
678  }
679 
680  int d = D_alignment_names.size();
681  switch (d) {
682  case 0:
683  error = GB_export_errorf("Cannot find a target alignment with a type of '%s'\n"
684  "You should create one first or select a different alignment type\n"
685  "during sequence import", src_type);
686  break;
687  case 1:
688  dest = D_alignment_names[0];
689  break;
690 
691  default:
692  if (autoselect_equal_alignment_name) {
693  for (int i = 0; i<d; ++i) {
694  if (ARB_stricmp(S_alignment_names[0], D_alignment_names[i]) == 0) {
695  dest = D_alignment_names[i];
696  break;
697  }
698  }
699  }
700 
701  if (!dest) {
702  GBS_strstruct buttonstr(100);
703 
704  for (int i=0; i<d; i++) {
705  buttonstr.cat(D_alignment_names[i]);
706  buttonstr.put(',');
707  }
708  buttonstr.cat("ABORT");
709 
710  int aliid = aw_question(NULp,
711  "There are more than one possible alignment targets\n"
712  "Choose one destination alignment or ABORT",
713  buttonstr.get_data());
714 
715  if (aliid >= d) {
716  error = "Operation Aborted";
717  break;
718  }
719  dest = D_alignment_names[aliid];
720  }
721  break;
722  }
723  if (!error && dest && strcmp(S_alignment_names[0], dest) != 0) {
724  error = GBT_rename_alignment(GLOBAL_gb_src, S_alignment_names[0], dest);
725  if (error) {
726  error = GBS_global_string("Failed to rename alignment '%s' to '%s' (Reason: %s)",
727  S_alignment_names[0], dest, error);
728  }
729  else {
731  }
732  }
733  free(src_type);
734  }
735 
736  return error;
737 }
738 
741 
742  static char *s_name = NULp;
743 
744  GB_HASH *D_species_hash = NULp;
745 
746  GB_topSecurityLevel srcUnsecured(GLOBAL_gb_src);
747  GB_topSecurityLevel dstUnsecured(GLOBAL_gb_dst);
750 
752  if (!error) {
753  GBDATA *S_species_data = GBT_get_species_data(GLOBAL_gb_src);
754  GBDATA *D_species_data = GBT_get_species_data(GLOBAL_gb_dst);
755 
756  freenull(s_name);
757 
758  {
759  long S_species_count = GB_number_of_subentries(S_species_data);
760  long D_species_count = GB_number_of_subentries(D_species_data);
761 
762  // create hash containing all species from gb_dst,
763  // but sized to hold all species from both DBs:
764  D_species_hash = GBT_create_species_hash_sized(GLOBAL_gb_dst, S_species_count+D_species_count);
765  }
766 
767  bool overwriteall = false;
768  bool autorenameall = false;
769 
770  for (GBDATA *S_species = GB_entry(S_species_data, "species"); S_species; S_species = GB_nextEntry(S_species)) {
771  GBDATA *S_name = GB_search(S_species, "name", GB_STRING);
772 
773  freeset(s_name, GB_read_string(S_name));
774 
775  int count = 1;
776  bool retry;
777  do {
778  retry = false;
779  count++;
780 
781  GBDATA *D_species = (GBDATA*)GBS_read_hash(D_species_hash, s_name);
782  if (D_species) {
783  if (overwriteall) {
784  error = GB_delete(D_species);
785  }
786  else if (autorenameall) {
787  GB_ERROR dummy;
788  char *newname = AWTC_create_numbered_suffix(D_species_hash, s_name, dummy);
789 
790  mg_assert(newname);
791  freeset(s_name, newname);
792  }
793  else {
794  switch (aw_question("merge_existing_species",
795  GBS_global_string("Warning: There is an ID conflict for species '%s'\n"
796  " You may:\n"
797  " - Overwrite existing species\n"
798  " - Overwrite all species with ID conflicts\n"
799  " - Not import species\n"
800  " - Enter ID for imported species\n"
801  " - Automatically create unique species IDs (append .NUM)\n"
802  " - Abort everything", s_name),
803  "overwrite, overwrite all, don't import, create ID, auto-create IDs, abort")) {
804  case 1:
805  overwriteall = true;
806  FALLTHROUGH;
807  case 0:
808  GB_delete(D_species);
809  break;
810 
811  case 2:
812  continue;
813 
814  case 3: {
815  GB_ERROR warning; // duplicated species warning (does not apply here)
816  char *autoname = AWTC_create_numbered_suffix(D_species_hash, s_name, warning);
817 
818  if (!autoname) autoname = ARB_strdup(s_name);
819  freeset(s_name, aw_input("Species ID", "Enter new species ID", autoname));
820  free(autoname);
821  retry = true;
822  break;
823  }
824  case 4:
825  autorenameall = true;
826  retry = true;
827  break;
828 
829  case 5:
830  error = "Operation aborted";
831  break;
832  }
833  }
834  }
835  } while (retry);
836 
837  if (!error) {
838  GBDATA *D_species = GB_create_container(D_species_data, "species");
839  if (!D_species) error = GB_await_error();
840  else {
841  error = GB_copy_dropMarksAndTempstate(D_species, S_species);
842 
843  if (!error) {
844  GB_write_flag(D_species, 1); // mark species
845  GB_raise_user_flag(D_species, GB_USERFLAG_QUERY); // put in search&query hitlist
846  error = GBT_write_string(D_species, "name", s_name);
847  }
848  }
849 
850  GBS_write_hash(D_species_hash, s_name, (long)D_species);
851  }
852 
853  if (error) break;
854  }
855  }
856 
857  if (D_species_hash) GBS_free_hash(D_species_hash);
858 
859  if (!error) error = MG_transfer_fields_info();
860  if (!error) awr->awar(AWAR_SPECIES_NAME)->write_string(s_name);
861 
862  error = taSrc.close(error);
863  error = taDst.close(error);
864 
865  aw_message_if(error);
866  return error;
867 }
868 
869 // -----------------------------
870 // MG_species_selector
871 
872 static void mg_select_species1(GBDATA*, AW_root *aw_root, const char *item_name) {
873  aw_root->awar(AWAR_SPECIES_SRC)->write_string(item_name);
874 }
875 static void mg_select_species2(GBDATA*, AW_root *aw_root, const char *item_name) {
876  aw_root->awar(AWAR_SPECIES_DST)->write_string(item_name);
877 }
878 
881 }
884 }
885 
888  const char *species_name = aw_root->awar(AWAR_SPECIES_SRC)->read_char_pntr();
889  return species_name[0] ? GBT_find_species(GLOBAL_gb_src, species_name) : NULp;
890 }
893  const char *species_name = aw_root->awar(AWAR_SPECIES_DST)->read_char_pntr();
894  return species_name[0] ? GBT_find_species(GLOBAL_gb_dst, species_name) : NULp;
895 }
896 
898 
900  static bool initialized = false;
901  if (!initialized) {
902  MG_species_selector[0] = MG_species_selector[1] = SPECIES_get_selector();
903 
904  for (int s = 0; s <= 1; ++s) {
905  MutableItemSelector& sel = MG_species_selector[s];
906 
910 
911  sel.items_name = sel.item_name = s ? "target species" : "source species";
912  }
913 
914  initialized = true;
915  }
916 }
917 
918 class ScopedTransporter { // @@@ later also use for old merge types (SXT_WHOLE_SPECIES + SXT_SINGLE_FIELD)
919  static QUERY::DbQuery *query2update;
920 
921  GBDATA *expect_selected_species(GBDATA *gb_main, const char *awarname_selected, const char *species_role, const char *listLocation, GB_ERROR& error, bool acceptNone) {
922  GBDATA *gb_species = NULp;
923  if (!error) {
924  const char *species_name = AW_root::SINGLETON->awar(awarname_selected)->read_char_pntr();
925  if (species_name[0]) {
926  gb_species = GBT_expect_species(gb_main, species_name);
927  if (!gb_species) {
928  error = GBS_global_string("%s (selected in %s hitlist)", GB_await_error(), listLocation);
929  }
930  }
931  else {
932  if (!acceptNone) {
933  error = GBS_global_string("Please select a %s species in %s hitlist", species_role, listLocation);
934  }
935  }
936  }
937 
938  mg_assert(implicated(!acceptNone, contradicted(error, gb_species)));
939  mg_assert(!(error && gb_species));
940 
941  return gb_species;
942  }
943 
944  GB_ERROR transferExistingOrNew(GBDATA *gb_src_item, GBDATA *gb_dst_item_container) {
945  GB_ERROR error = NULp;
946  const char *name = GBT_get_name(gb_src_item);
947 
948  if (!name) {
949  error = "unnamed item";
950  }
951  else {
952  GBDATA *gb_dst_item = GBT_find_species_rel_species_data(gb_dst_item_container, name);
953  if (gb_dst_item) { // found existing species
954  error = transferOne(gb_src_item, gb_dst_item, NULp); // use it as target
955  }
956  else { // not found
957  if (GB_have_error()) { // due to error
958  error = GB_await_error();
959  }
960  else { // otherwise create new species
961  error = transferOne(gb_src_item, NULp, gb_dst_item_container);
962  }
963  }
964  }
965  return error;
966  }
967 
968 protected:
969  static void markTarget(GBDATA *gb_dst_item) {
970  mg_assert(GB_is_ancestor_of(GLOBAL_gb_dst, gb_dst_item)); // only modify userflag of destination(!) database
971 
972  GB_write_flag(gb_dst_item, 1); // mark species
973  GB_raise_user_flag(gb_dst_item, GB_USERFLAG_QUERY); // put in search&query (destination) hitlist
974  }
975 
976 public:
977  virtual ~ScopedTransporter() {}
978 
979  static void set_query_to_update(QUERY::DbQuery *query) { query2update = query; }
980 
981  virtual GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container) = 0;
988  GB_ERROR transferAllIn(SpeciesXferScope scope, const char *progressTitle) {
991 
992  {
993  unsigned long scopeSize = 0;
994  switch (scope) {
995  case SXS_SELECTED_SPECIES: scopeSize = 1; break;
996  case SXS_LISTED_SPECIES: scopeSize = mg_count_queried(GLOBAL_gb_src); break;
997  }
998 
999  arb_progress progress(progressTitle, scopeSize);
1000 
1001  GBDATA *gb_dst_species_container = GBT_get_species_data(GLOBAL_gb_dst);
1002  if (!error) {
1003  switch (scope) {
1004  case SXS_SELECTED_SPECIES: {
1005  GBDATA *gb_src_species = expect_selected_species(GLOBAL_gb_src, AWAR_SPECIES_SRC, "source", "left", error, false);
1006  GBDATA *gb_dst_species = expect_selected_species(GLOBAL_gb_dst, AWAR_SPECIES_DST, "target", "right", error, true);
1007 
1008  if (!error) {
1009  if (gb_dst_species) { // source and target explicitely selected
1010  error = transferOne(gb_src_species, gb_dst_species, NULp);
1011  }
1012  else {
1013  error = transferExistingOrNew(gb_src_species, gb_dst_species_container);
1014  }
1015  progress.inc_and_check_user_abort(error);
1016  }
1017  break;
1018  }
1019 
1020  case SXS_LISTED_SPECIES: {
1021  for (GBDATA *gb_src_species = GBT_first_species(GLOBAL_gb_src);
1022  gb_src_species && !error;
1023  gb_src_species = GBT_next_species(gb_src_species))
1024  {
1025  if (IS_QUERIED_SPECIES(gb_src_species)) {
1026  error = transferExistingOrNew(gb_src_species, gb_dst_species_container);
1027  if (error) { // mention name of species in error message:
1028  error = GBS_global_string("%s (species=%s)", error, GBT_get_name_or_description(gb_src_species));
1029  }
1030  progress.inc_and_check_user_abort(error);
1031  }
1032  }
1033  break;
1034  }
1035  }
1036  }
1037 
1038  if (error) progress.done();
1039  }
1040  error = GB_end_transaction(GLOBAL_gb_src, error);
1041  error = GB_end_transaction(GLOBAL_gb_dst, error);
1042 
1043  if (!error && query2update) DbQuery_update_list(query2update); // no need to update in case of error
1044 
1045  return error;
1046  }
1047 };
1048 
1049 QUERY::DbQuery *ScopedTransporter::query2update = NULp;
1050 
1051 using namespace FieldTransfer;
1052 
1054 
1056  MG_remapsPtr remaps;
1057 
1058 public:
1059  AdaptedAlignmentTransporter(MG_remapsPtr remaps_) : remaps(remaps_) {}
1060  bool shallCopyBefore() const OVERRIDE {
1061  return true; // ItemClonedByRuleSet::copyAlignments() shall be called b4 calling transport()
1062  }
1063  GB_ERROR transport(GBDATA *gb_src_item, GBDATA *gb_dst_item) const OVERRIDE {
1064  return MG_adaptAllCopiedAlignments(*remaps, gb_src_item, gb_dst_item);
1065  }
1066 };
1067 
1069  // this AlignmentTransporter simply does not transport anything
1070  bool shallCopyBefore() const OVERRIDE { return false; } // do not call copyAlignments() b4 calling transport()
1071  GB_ERROR transport(GBDATA *, GBDATA *) const OVERRIDE { return NULp; } // do not transport alignment data
1072 };
1073 
1074 
1075 
1077  RuleSetPtr fts;
1078  AlignmentTransporterPtr aliTransporter;
1079 
1080 public:
1082  fts(fts_),
1083  aliTransporter(transp)
1084  {}
1085  GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container) OVERRIDE {
1086  mg_assert(fts.isSet());
1087  mg_assert(contradicted(gb_dst_item, gb_dst_item_container)); // exactly one of both shall be set
1088 
1089  GB_ERROR error = NULp;
1090  GBDATA *gb_transferred = NULp;
1091  {
1092  ItemClonedByRuleSet transfer(gb_src_item, CLONE_ITEM_SPECIES, fts,
1093  gb_dst_item ? CLONE_INTO_EXISTING : REAL_CLONE,
1094  gb_dst_item ? gb_dst_item : gb_dst_item_container,
1095  &*aliTransporter);
1096 
1097  if (transfer.has_error()) {
1098  error = transfer.get_error();
1099  }
1100  else {
1101  gb_transferred = transfer.get_clone();
1102  }
1103  }
1104 
1105  mg_assert(contradicted(error, gb_transferred));
1106  if (!error) markTarget(gb_transferred);
1107 
1108  return error;
1109  }
1110 };
1111 
1112 static void mg_xfer_via_fts(AW_root *aw_root, SpeciesXferScope scope, bool xfer_seq_data) {
1113  if (MG_copy_and_check_alignments() != 0) return;
1114 
1115  GB_ERROR error = NULp;
1116  const char *ftsname = XFER_getFullFTS(aw_root->awar(AWAR_SPECIES_XFER_FTS)->read_char_pntr());
1117 
1118  if (!ftsname[0]) {
1119  error = "No FTS selected";
1120  }
1121  else {
1122  ErrorOrRuleSetPtr loaded = RuleSet::loadFrom(ftsname);
1123  if (loaded.hasError()) {
1124  ARB_ERROR lerror = loaded.getError();
1125  error = lerror.deliver();
1126  }
1127  else {
1128  AlignmentTransporterPtr transport_ali;
1129  if (xfer_seq_data) {
1130  MG_remapsPtr remaps;
1131  {
1132  GB_transaction ta_src(GLOBAL_gb_src);
1133  GB_transaction ta_dst(GLOBAL_gb_dst);
1134  remaps = new MG_remaps(GLOBAL_gb_src, GLOBAL_gb_dst, adaption_enabled(aw_root), get_reference_species_names(aw_root)); // @@@ use factory to make MG_remaps / MG_remapsPtr
1135  // @@@ can MG_remaps report error? (e.g. if wrong SAI/species specified as reference)
1136  }
1137 
1138  transport_ali = new AdaptedAlignmentTransporter(remaps);
1139  }
1140  else {
1141  transport_ali = new DontTransportAlignment;
1142  }
1143 
1144  ViaFtsTransporter transporter(loaded.getValue(), transport_ali);
1145  error = transporter.transferAllIn(scope, "Transfer using FTS");
1146  }
1147  }
1148  aw_message_if(error);
1149 }
1150 
1152  void scanFields(StrArray& fields, FieldsToScan whatToScan) const OVERRIDE {
1153  if (whatToScan & SCAN_INPUT_FIELDS) {
1155  }
1156  if (whatToScan & SCAN_OUTPUT_FIELDS) {
1158  }
1159  }
1160 };
1161 
1163 
1164 static void MG_transfer_species(AW_window *aww) {
1165  AW_root *awr = aww->get_root();
1166 
1169 
1170  switch (type) {
1171  case SXT_WHOLE_SPECIES:
1172  switch (scope) {
1175  }
1176  break;
1177 
1178  case SXT_SINGLE_FIELD:
1180  break;
1181 
1182  case SXT_USING_FTS:
1183  case SXT_USING_FTS_SKIP_ALI: {
1184  bool xfer_seq_data = (type == SXT_USING_FTS);
1185  mg_xfer_via_fts(awr, scope, xfer_seq_data);
1186  break;
1187  }
1188  }
1189 }
1190 
1193  if (error) {
1194  aw_message(error);
1195  return NULp; // deny to open window before user has renamed species
1196  }
1197 
1200 
1202  aws->init(awr, "MERGE_TRANSFER_SPECIES", "TRANSFER SPECIES");
1203  aws->load_xfig("merge/species.fig");
1204 
1205  aws->at("close");
1206  aws->callback(AW_POPDOWN);
1207  aws->create_button("CLOSE", "CLOSE", "C");
1208 
1209  aws->at("help");
1210  aws->callback(makeHelpCallback("mg_species.hlp"));
1211  aws->create_button("HELP", "HELP", "H");
1212 
1214 
1215  // define macro IDs and window titles for both config managers used in transfer window:
1216  AWT_predef_config_manager("MERGE_TRANSFER_SOURCE_SPECIES_config", "Configurations for source species query");
1217  AWT_predef_config_manager("MERGE_TRANSFER_TARGET_SPECIES_config", "Configurations for target species query");
1218 
1219  {
1220  QUERY::query_spec awtqs(MG_species_selector[0]);
1221  aws->create_menu("Source-DB", "S");
1222 
1223  awtqs.gb_main = GLOBAL_gb_src;
1224  awtqs.gb_ref = GLOBAL_gb_dst;
1225  awtqs.expect_hit_in_ref_list = false;
1227  awtqs.tree_name = NULp; // no selected tree here -> can't use tree related ACI commands without specifying a tree
1228  awtqs.select_bit = GB_USERFLAG_QUERY;
1229  awtqs.ere_pos_fig = "ere1";
1230  awtqs.by_pos_fig = "by1";
1231  awtqs.qbox_pos_fig = "qbox1";
1232  awtqs.key_pos_fig = NULp;
1233  awtqs.query_pos_fig = "content1";
1234  awtqs.result_pos_fig = "result1";
1235  awtqs.count_pos_fig = "count1";
1236  awtqs.do_query_pos_fig = "doquery1";
1237  awtqs.config_pos_fig = "doconfig1";
1238  awtqs.do_mark_pos_fig = NULp;
1239  awtqs.do_unmark_pos_fig = NULp;
1240  awtqs.do_delete_pos_fig = "dodelete1";
1241  awtqs.do_set_pos_fig = "doset1";
1242  awtqs.do_refresh_pos_fig = "dorefresh1";
1243  awtqs.open_parser_pos_fig = "openparser1";
1244  awtqs.use_menu = 1;
1245 
1246  create_query_box(aws, &awtqs, "db1");
1247 
1248  DbScanner *scanner = DbScanner::create(GLOBAL_gb_src, "merge_spec1", aws, "box1", NULp, NULp, DB_SCANNER, NULp, awtqs.get_queried_itemtype());
1249  scanner_src = scanner;
1250  aws->get_root()->awar(AWAR_SPECIES_SRC)->add_callback(makeRootCallback(MG_map_species, SRC_DB));
1251  }
1252  {
1253  QUERY::query_spec awtqs(MG_species_selector[1]);
1254  aws->create_menu("Target-DB", "T");
1255 
1256  awtqs.gb_main = GLOBAL_gb_dst;
1257  awtqs.gb_ref = GLOBAL_gb_src;
1258  awtqs.expect_hit_in_ref_list = true;
1260  awtqs.select_bit = GB_USERFLAG_QUERY;
1261  awtqs.ere_pos_fig = "ere2";
1262  awtqs.by_pos_fig = "by2";
1263  awtqs.qbox_pos_fig = "qbox2";
1264  awtqs.key_pos_fig = NULp;
1265  awtqs.query_pos_fig = "content2";
1266  awtqs.result_pos_fig = "result2";
1267  awtqs.count_pos_fig = "count2";
1268  awtqs.do_query_pos_fig = "doquery2";
1269  awtqs.config_pos_fig = "doconfig2";
1270  awtqs.do_mark_pos_fig = NULp;
1271  awtqs.do_unmark_pos_fig = NULp;
1272  awtqs.do_delete_pos_fig = "dodelete2";
1273  awtqs.do_set_pos_fig = "doset2";
1274  awtqs.do_refresh_pos_fig = "dorefresh2";
1275  awtqs.open_parser_pos_fig = "openparser2";
1276  awtqs.use_menu = 1;
1277 
1279 
1280  DbScanner *scanner = DbScanner::create(GLOBAL_gb_dst, "merge_spec2", aws, "box2", NULp, NULp, DB_SCANNER, NULp, awtqs.get_queried_itemtype());
1281  scanner_dst = scanner;
1282  aws->get_root()->awar(AWAR_SPECIES_DST)->add_callback(makeRootCallback(MG_map_species, DST_DB));
1283  }
1284 
1285  // ---------------------
1286  // middle area
1287 
1288  // top icon
1289  aws->button_length(0);
1290  aws->at("icon");
1291  aws->callback(makeHelpCallback("mg_species.hlp"));
1292  aws->create_button("HELP_MERGE", "#merge/icon.xpm");
1293 
1294  // adapt alignments
1295  {
1296  if (dst_is_new) {
1297  aws->sens_mask(AWM_DISABLED); // if dest DB is new = > adaption impossible
1298  awr->awar(AWAR_REMAP_ENABLE)->write_int(0); // disable adaption
1299  }
1300 
1301  aws->at("adapt");
1303 
1304  aws->at("reference");
1306 
1307  aws->at("pres_sel");
1309  aws->create_autosize_button("SELECT", "SELECT", "S");
1310 
1311  aws->sens_mask(AWM_ALL);
1312  }
1313 
1314  // transfer options:
1315  aws->at("xferType");
1317  aws->insert_option("whole species", "w", SXT_WHOLE_SPECIES);
1318  aws->insert_option("single field", "s", SXT_SINGLE_FIELD);
1319  aws->insert_option("using FTS (with seq)", "F", SXT_USING_FTS);
1320  aws->insert_option("using FTS (w/o seq)", "o", SXT_USING_FTS_SKIP_ALI);
1321  aws->update_option_menu();
1322 
1323  aws->at("fts");
1324  aws->callback(makeWindowCallback(XFER_select_RuleSet, AWAR_SPECIES_XFER_FTS, static_cast<AvailableFieldScanner*>(&fieldScanner)));
1325  aws->create_button("SELECT_FTS", AWAR_SPECIES_XFER_FTS);
1326 
1327  aws->at("xferWhat");
1329  aws->insert_option("listed species", "l", SXS_LISTED_SPECIES);
1330  aws->insert_option("selected species", "s", SXS_SELECTED_SPECIES);
1331  aws->update_option_menu();
1332 
1333  {
1334  aws->shadow_width(3);
1335 
1336  aws->at("transfer");
1338  aws->create_button("TRANSFER", "Transfer species");
1339 
1340  aws->shadow_width(1);
1341  }
1342 
1343  aws->create_menu("Source->Target", "g");
1344  aws->insert_menu_topic("compare_field_of_listed", "Compare a field of listed species ...", "C", "checkfield.hlp", AWM_ALL, create_mg_check_fields_window);
1345  aws->insert_menu_topic("merge_field_of_listed_to_new_field", "Merge tagged field ...", "M", "mergetaggedfield.hlp", AWM_ALL, create_mg_merge_tagged_fields_window);
1346  aws->sep______________();
1347  aws->insert_menu_topic("def_gene_species_field_xfer", "Define field transfer for gene-species", "g", "gene_species_field_transfer.hlp", AWM_ALL, MG_gene_species_create_field_transfer_def_window);
1348 
1349 
1350  return aws;
1351 }
1352 
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2528
void insert_option(AW_label choice_label, const char *mnemonic, const char *var_value, const char *name_of_color=NULp)
GB_ERROR GB_copy_dropProtectMarksAndTempstate(GBDATA *dest, GBDATA *source)
Definition: arbdb.cxx:2152
AW_window * create_mg_check_fields_window(AW_root *aw_root)
#define AWAR_SPECIES_XFER_SCOPE
Definition: MG_species.cxx:46
const char * GB_ERROR
Definition: arb_core.h:25
GB_ERROR transferAllIn(SpeciesXferScope scope, const char *progressTitle)
Definition: MG_species.cxx:988
const char * item_name
Definition: items.h:65
GB_TYPES type
void button_length(int length)
Definition: AW_at.cxx:288
size_t size() const
Definition: arb_strarray.h:85
GB_ERROR transport(GBDATA *, GBDATA *) const OVERRIDE
static void MG_map_species(AW_root *aw_root, DbSel db)
Definition: MG_species.cxx:81
static MutableItemSelector MG_species_selector[2]
Definition: MG_species.cxx:897
void sens_mask(AW_active mask)
Definition: AW_window.cxx:136
void scanFields(StrArray &fields, FieldsToScan whatToScan) const OVERRIDE
long GB_read_int(GBDATA *gbd)
Definition: arbdb.cxx:729
#define implicated(hypothesis, conclusion)
Definition: arb_assert.h:289
void XFER_select_RuleSet(AW_window *aww, const char *awar_selected_fts, const AvailableFieldScanner *fieldScanner)
Definition: xfergui.cxx:1204
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
Definition: adhash.cxx:454
const char * config_pos_fig
Definition: db_query.h:61
AwarName species_name
Definition: db_query.h:42
void insert_menu_topic(const char *id, const char *name, const char *mnemonic, const char *help_text_, AW_active mask, const WindowCallback &wcb)
Definition: AW_window.cxx:604
AW_window * MG_gene_species_create_field_transfer_def_window(AW_root *aw_root)
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
Definition: arbdb.cxx:1387
bool fieldContainsAlignment(const char *field)
Definition: MG_species.cxx:354
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:729
void DbQuery_update_list(DbQuery *query)
Definition: db_query.cxx:486
GB_ERROR GBT_rename_alignment(GBDATA *gbMain, const char *source, const char *dest)
Definition: adali.cxx:597
static void transfer_field_of_selected_cb(AW_window *aww)
Definition: MG_species.cxx:439
static void mg_select_species2(GBDATA *, AW_root *aw_root, const char *item_name)
Definition: MG_species.cxx:875
bool shallCopyBefore() const OVERRIDE
const char * key_pos_fig
Definition: db_query.h:53
#define AWAR_REMAP_SPECIES_LIST
Definition: merge.hxx:76
static GBDATA * mg_get_first_species_data2(GBDATA *, AW_root *, QUERY_RANGE)
Definition: MG_species.cxx:882
int MG_copy_and_check_alignments()
static void transfer_field_of_listed_cb(AW_window *aww)
Definition: MG_species.cxx:358
GBDATA * GB_nextEntry(GBDATA *entry)
Definition: adquery.cxx:339
GB_ERROR GB_end_transaction(GBDATA *gbd, GB_ERROR error)
Definition: arbdb.cxx:2561
void at(int x, int y)
Definition: AW_at.cxx:93
const char * ere_pos_fig
Definition: db_query.h:48
int ARB_stricmp(const char *s1, const char *s2)
Definition: arb_str.h:28
static const char * get_reference_species_names(AW_root *awr)
Definition: MG_species.cxx:203
void GBT_get_alignment_names(ConstStrArray &names, GBDATA *gbd)
Definition: adali.cxx:317
static MergeFieldScanner fieldScanner
static void mg_transfer_listed_species(AW_window *aww)
Definition: MG_species.cxx:257
static GB_ERROR transfer_single_field(GBDATA *const gb_src_species, GBDATA *const gb_dst_species, const char *const field, GBDATA *const gb_src_field, const bool append, const bool transfer_of_alignment, const MG_remaps &rm)
Definition: MG_species.cxx:304
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
void create_toggle(const char *awar_name)
Definition: AW_button.cxx:844
void GB_end_transaction_show_error(GBDATA *gbd, GB_ERROR error, void(*error_handler)(GB_ERROR))
Definition: arbdb.cxx:2584
long read_int() const
Definition: AW_awar.cxx:184
bool hasError() const
Definition: ErrorOrType.h:50
TYPE getValue() const
Definition: ErrorOrType.h:58
DbQuery * create_query_box(AW_window *aws, query_spec *awtqs, const char *query_id)
Definition: db_query.cxx:2338
ViaFtsTransporter(RuleSetPtr fts_, AlignmentTransporterPtr transp)
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
Definition: merge.hxx:35
void warning(int warning_num, const char *warning_message)
Definition: util.cxx:61
const char * result_pos_fig
Definition: db_query.h:57
static DbScanner * scanner_dst
Definition: MG_species.cxx:50
static void markTarget(GBDATA *gb_dst_item)
Definition: MG_species.cxx:969
GB_ERROR MG_expect_renamed()
Definition: MG_names.cxx:119
bool GB_have_error()
Definition: arb_msg.cxx:338
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
static GB_ERROR MG_transfer_one_species(AW_root *aw_root, MG_remaps &remap, GBDATA *gb_src_species, GBDATA *gb_dst_species_data, bool src_is_genome, bool dst_is_genome, GB_HASH *source_organism_hash, GB_HASH *dest_species_hash, GB_HASH *error_suppressor)
Definition: MG_species.cxx:126
void GBS_free_hash(GB_HASH *hs)
Definition: adhash.cxx:538
GBDATA * GEN_find_organism(GBDATA *gb_main, const char *name)
Definition: adGene.cxx:728
static AW_window * create_mg_merge_tagged_fields_window(AW_root *aw_root)
Definition: MG_species.cxx:620
GB_HASH * GBT_create_species_hash(GBDATA *gb_main)
Definition: adhashtools.cxx:36
void cat(const char *from)
Definition: arb_strbuf.h:199
const char * MG_left_AWAR_SPECIES_NAME()
Definition: MG_species.cxx:64
SpeciesXferScope
Definition: MG_species.cxx:59
GB_ERROR MG_export_fields(AW_root *aw_root, GBDATA *gb_src, GBDATA *gb_dst, GB_HASH *error_suppressor, GB_HASH *source_organism_hash)
const char * open_parser_pos_fig
Definition: db_query.h:70
char * GBT_get_alignment_type_string(GBDATA *gb_main, const char *aliname)
Definition: adali.cxx:873
GBDATA * GB_get_father(GBDATA *gbd)
Definition: arbdb.cxx:1722
void update_option_menu()
void activate()
Definition: aw_window.hxx:365
GBDATA * GLOBAL_gb_dst
Definition: MG_main.cxx:31
#define NO_FIELD_SELECTED
GB_CSTR GBS_find_string(GB_CSTR cont, GB_CSTR substr, int match_mode)
Definition: admatch.cxx:103
#define AWAR_FIELD_SRC
Definition: MG_species.cxx:35
SpeciesXferType
Definition: MG_species.cxx:52
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
GB_ERROR GB_delete(GBDATA *&source)
Definition: arbdb.cxx:1916
GB_ERROR GBT_add_alignment_changekeys(GBDATA *gb_main, const char *ali)
void create_itemfield_selection_button(AW_window *aws, const FieldSelDef &selDef, const char *at)
static bool initialized
Definition: AW_advice.cxx:36
GB_ERROR MERGE_sequences_simple(AW_root *awr)
Definition: MG_species.cxx:739
static void popup_single_field_transfer_window(AW_root *aw_root, SpeciesXferScope scope)
Definition: MG_species.cxx:507
void GB_raise_user_flag(GBDATA *gbd, unsigned char user_bit)
Definition: arbdb.cxx:2755
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
GB_ERROR MG_adaptAllCopiedAlignments(const MG_remaps &remaps, GBDATA *source_species, GBDATA *destination_species)
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:257
GB_ERROR GBT_add_new_species_changekey(GBDATA *gb_main, const char *name, GB_TYPES type)
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
static AW_root * SINGLETON
Definition: aw_root.hxx:102
GBDATA * GB_create_container(GBDATA *father, const char *key)
Definition: arbdb.cxx:1829
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
char * GBT_read_string(GBDATA *gb_container, const char *fieldpath)
Definition: adtools.cxx:267
Definition: arbdb.h:78
GB_TYPES GB_read_type(GBDATA *gbd)
Definition: arbdb.cxx:1643
GB_ERROR deliver() const
Definition: arb_error.h:116
static GB_ERROR MG_transfer_fields_info(char *fieldname=NULp)
Definition: MG_species.cxx:96
bool isSet() const
test if SmartPtr is not NULp
Definition: smartptr.h:245
long GB_number_of_subentries(GBDATA *gbd)
Definition: arbdb.cxx:2892
static GB_ERROR MG_equal_alignments(bool autoselect_equal_alignment_name)
Definition: MG_species.cxx:659
GBDATA * gb_ref
Definition: db_query.h:40
SmartPtr< MG_remaps > MG_remapsPtr
static void mg_transfer_selected_species(AW_window *aww)
Definition: MG_species.cxx:210
GBDATA *(* get_selected_item)(GBDATA *gb_main, AW_root *aw_root)
Definition: items.h:75
#define mg_assert(bed)
Definition: merge.hxx:24
static void MG_transfer_species(AW_window *aww)
bool GB_is_ancestor_of(GBDATA *gb_ancestor, GBDATA *gb_descendant)
Definition: arbdb.cxx:1744
void create_menu(const char *name, const char *mnemonic, AW_active mask=AWM_ALL)
Definition: AW_window.cxx:481
const char * qbox_pos_fig
Definition: db_query.h:52
GBDATA * GBT_expect_species(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:146
static void MG_merge_tagged_field_cb(AW_window *aww)
Definition: MG_species.cxx:549
GBDATA *(* get_first_item_container)(GBDATA *, AW_root *, QUERY_RANGE)
Definition: items.h:69
static void error(const char *msg)
Definition: mkptypes.cxx:96
static GBDATA * mg_get_first_species_data1(GBDATA *, AW_root *, QUERY_RANGE)
Definition: MG_species.cxx:879
void remove(int i)
char * GBT_readOrCreate_string(GBDATA *gb_container, const char *fieldpath, const char *default_value)
Definition: adtools.cxx:371
GBDATA * GBT_find_or_create_species_rel_species_data(GBDATA *gb_species_data, const char *name, bool markCreated)
Definition: aditem.cxx:57
static void mg_xfer_via_fts(AW_root *aw_root, SpeciesXferScope scope, bool xfer_seq_data)
FieldsToScan
Definition: xfergui.h:21
#define CHANGEKEY_NAME
Definition: arbdbt.h:92
const char * GEN_origin_organism(GBDATA *gb_pseudo)
Definition: adGene.cxx:549
long mg_count_queried(GBDATA *gb_main)
static DbScanner * scanner_src
Definition: MG_species.cxx:49
const char * items_name
Definition: items.h:66
void AWT_predef_config_manager(const char *macro_id, const char *window_title)
#define AWAR_SPECIES_NAME
const char * count_pos_fig
Definition: db_query.h:58
DbSel
Definition: merge.hxx:35
#define AWAR_FIELD_DST
Definition: MG_species.cxx:39
static DbScanner * create(GBDATA *gb_main, const char *scanner_id, AW_window *aws, const char *box_pos_fig, const char *edit_pos_fig, const char *edit_enable_pos_fig, DB_SCANNERMODE scannermode, const char *mark_pos_fig, ItemSelector &selector)
Definition: db_scanner.cxx:227
const char * by_pos_fig
Definition: db_query.h:50
GBDATA * GBT_find_species_rel_species_data(GBDATA *gb_species_data, const char *name)
Definition: aditem.cxx:133
char * read_string() const
Definition: AW_awar.cxx:198
GB_ERROR get_error() const
Definition: xferset.h:325
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:568
bool expect_hit_in_ref_list
Definition: db_query.h:41
const char * XFER_getFullFTS(const char *name)
Definition: xfergui.cxx:96
Definition: arbdb.h:86
CONSTEXPR long FIELD_FILTER_ANY_FIELD
Definition: item_sel_list.h:50
void create_autosize_button(const char *macro_name, AW_label label, const char *mnemonic=NULp, unsigned xtraSpace=1)
Definition: AW_button.cxx:421
GBDATA * GLOBAL_gb_src
Definition: MG_main.cxx:30
#define AWAR_SPECIES_DST
Definition: MG_species.cxx:38
#define AWAR_TAG_SRC
Definition: MG_species.cxx:36
static void set_query_to_update(QUERY::DbQuery *query)
Definition: MG_species.cxx:979
void MG_create_species_awars(AW_root *aw_root, AW_default aw_def)
Definition: MG_species.cxx:66
QUERY_RANGE
Definition: items.h:40
void(* update_item_awars)(GBDATA *gb_main, AW_root *aw_root, const char *item_name)
Definition: items.h:57
int aw_question(const char *unique_id, const char *question, const char *buttons, bool sameSizeButtons, const char *helpfile)
Definition: AW_question.cxx:26
GB_ERROR GB_export_errorf(const char *templat,...)
Definition: arb_msg.cxx:262
AdaptedAlignmentTransporter(MG_remapsPtr remaps_)
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:594
AW_window * MG_create_preserves_selection_window(AW_root *awr)
GB_ERROR close(GB_ERROR error)
Definition: arbdbpp.cxx:35
void GB_write_flag(GBDATA *gbd, long flag)
Definition: arbdb.cxx:2773
Definition: merge.hxx:35
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
Definition: adtools.cxx:451
#define AWAR_APPEND
Definition: MG_species.cxx:43
#define OVERRIDE
Definition: cxxforward.h:112
const char * do_mark_pos_fig
Definition: db_query.h:63
char * AWTC_create_numbered_suffix(GB_HASH *species_name_hash, const char *shortname, GB_ERROR &warning)
Definition: AW_rename.cxx:446
#define AWAR_SPECIES_XFER_FTS
Definition: MG_species.cxx:47
static GBDATA * mg_get_selected_species1(GBDATA *, AW_root *aw_root)
Definition: MG_species.cxx:886
#define CHANGE_KEY_PATH
Definition: arbdbt.h:87
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:909
GB_ERROR GB_copy_dropMarksAndTempstate(GBDATA *dest, GBDATA *source)
Definition: arbdb.cxx:2163
void Map(GBDATA *gb_new_item, const char *key_path)
Definition: db_scanner.cxx:489
ItemSelector & SPECIES_get_selector()
Definition: species.cxx:140
GBDATA * GBT_first_species(GBDATA *gb_main)
Definition: aditem.cxx:124
#define CHANGEKEY
Definition: arbdbt.h:91
#define CHANGEKEY_TYPE
Definition: arbdbt.h:93
#define IS_QUERIED_SPECIES(gb_species)
Definition: merge.hxx:79
const char * query_pos_fig
Definition: db_query.h:54
static void mg_select_species1(GBDATA *, AW_root *aw_root, const char *item_name)
Definition: MG_species.cxx:872
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
const char * do_query_pos_fig
Definition: db_query.h:60
AW_option_menu_struct * create_option_menu(const char *awar_name)
GBDATA * GB_find_string(GBDATA *gbd, const char *key, const char *str, GB_CASE case_sens, GB_SEARCH_TYPE gbs)
Definition: adquery.cxx:302
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 * GBT_find_species(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:139
GB_HASH * GBT_create_organism_hash(GBDATA *gb_main)
Definition: adhashtools.cxx:48
#define AWAR_TAG_DEL
Definition: MG_species.cxx:42
#define AWAR_SPECIES_XFER_TYPE
Definition: MG_species.cxx:45
virtual GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container)=0
GB_ERROR write_string(const char *aw_string)
static ErrorOrRuleSetPtr loadFrom(const char *filename)
Definition: xferset.cxx:368
const char * get_data() const
Definition: arb_strbuf.h:120
GB_HASH * GBT_create_species_hash_sized(GBDATA *gb_main, long species_count)
Definition: adhashtools.cxx:32
const char * GBT_get_name(GBDATA *gb_item)
Definition: aditem.cxx:468
void sep______________()
Definition: AW_window.cxx:762
#define GB_USERFLAG_QUERY
Definition: arbdb.h:55
GB_TYPES
Definition: arbdb.h:62
ARB_ERROR getError() const
Definition: ErrorOrType.h:53
bool shallCopyBefore() const OVERRIDE
virtual ~ScopedTransporter()
Definition: MG_species.cxx:977
#define FALLTHROUGH
Definition: cxxforward.h:136
#define AWAR_SPECIES_SRC
Definition: MG_species.cxx:34
GB_transaction ta(gb_var)
void callback(const WindowCallback &cb)
Definition: AW_window.cxx:142
GBDATA * gb_main
Definition: db_query.h:39
GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container) OVERRIDE
GBDATA * gb_main
Definition: adname.cxx:32
ItemSelector & get_queried_itemtype() const
Definition: db_query.h:37
char * GBS_merge_tagged_strings(const char *s1, const char *tag1, const char *replace1, const char *s2, const char *tag2, const char *replace2)
Definition: adstring.cxx:710
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:584
CONSTEXPR long FIELD_FILTER_STRING
Definition: item_sel_list.h:41
bool GBS_string_matches(const char *str, const char *expr, GB_CASE case_sens)
Definition: admatch.cxx:193
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
Definition: adquery.cxx:531
GB_CSTR GBT_get_name_or_description(GBDATA *gb_item)
Definition: aditem.cxx:459
bool GEN_is_genome_db(GBDATA *gb_main, int default_value)
Definition: adGene.cxx:20
void shadow_width(int shadow_thickness)
Definition: AW_window.cxx:1087
const char * do_set_pos_fig
Definition: db_query.h:69
char * aw_input(const char *title, const char *prompt, const char *default_input)
Definition: AW_modal.cxx:252
static GBDATA * mg_get_selected_species2(GBDATA *, AW_root *aw_root)
Definition: MG_species.cxx:891
#define AWAR_REMAP_ENABLE
Definition: merge.hxx:77
GBDATA * get_gb_main(DbSel db)
Definition: merge.hxx:88
bool GEN_is_pseudo_gene_species(GBDATA *gb_species)
Definition: adGene.cxx:558
AW_window * MG_create_merge_species_window(AW_root *awr, bool dst_is_new)
static bool adaption_enabled(AW_root *awr)
Definition: MG_species.cxx:206
#define AWAR_TAG_DST
Definition: MG_species.cxx:40
AwarName tree_name
Definition: db_query.h:43
GB_ERROR write_int(long aw_int)
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:392
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
void init(AW_root *root, const char *wid, const char *windowname)
Definition: AW_window.cxx:2866
void collectKeysRegisteredInDatabase(StrArray &fields, GBDATA *gb_main, ItemSelector &sel, bool skipContainers, bool skipHidden)
Definition: db_scanner.cxx:522
void create_text_field(const char *awar_name, int columns=20, int rows=4)
Definition: AW_button.cxx:988
const char * do_delete_pos_fig
Definition: db_query.h:68
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
const char * do_unmark_pos_fig
Definition: db_query.h:64
const char * do_refresh_pos_fig
Definition: db_query.h:71
static void mg_initialize_species_selectors()
Definition: MG_species.cxx:899
CONSTEXPR long FIELD_UNFILTERED
Definition: item_sel_list.h:49
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
Definition: adhash.cxx:253
void put(char c)
Definition: arb_strbuf.h:174
void create_button(const char *macro_name, AW_label label, const char *mnemonic=NULp, const char *color=NULp)
Definition: AW_button.cxx:448
GBDATA * GBT_get_species_data(GBDATA *gb_main)
Definition: aditem.cxx:105
GB_ERROR transport(GBDATA *gb_src_item, GBDATA *gb_dst_item) const OVERRIDE
GB_write_int const char s
Definition: AW_awar.cxx:154