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