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