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_changekey(GLOBAL_gb_dst, name, (int)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, 1, 1);
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 
885 static GBDATA *mg_get_selected_species1(GBDATA * /* gb_main */, AW_root *aw_root) {
887  char *species_name = aw_root->awar(AWAR_SPECIES_SRC)->read_string();
888  GBDATA *gb_species = NULp;
889  if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_src, species_name);
890  free(species_name);
891  return gb_species;
892 }
893 static GBDATA *mg_get_selected_species2(GBDATA * /* gb_main */, AW_root *aw_root) {
895  char *species_name = aw_root->awar(AWAR_SPECIES_DST)->read_string();
896  GBDATA *gb_species = NULp;
897  if (species_name[0]) gb_species = GBT_find_species(GLOBAL_gb_dst, species_name);
898  free(species_name);
899  return gb_species;
900 }
901 
903 
905  static int initialized = 0;
906  if (!initialized) {
907  MG_species_selector[0] = MG_species_selector[1] = SPECIES_get_selector();
908 
909  for (int s = 0; s <= 1; ++s) {
910  MutableItemSelector& sel = MG_species_selector[s];
911 
915  }
916 
917  initialized = 1;
918  }
919 }
920 
921 class ScopedTransporter { // @@@ later also use for old merge types (SXT_WHOLE_SPECIES + SXT_SINGLE_FIELD)
922  static QUERY::DbQuery *query2update;
923 
924  GBDATA *expect_selected_species(GBDATA *gb_main, const char *awarname_selected, const char *species_role, const char *listLocation, GB_ERROR& error, bool acceptNone) {
925  GBDATA *gb_species = NULp;
926  if (!error) {
927  const char *species_name = AW_root::SINGLETON->awar(awarname_selected)->read_char_pntr();
928  if (species_name[0]) {
929  gb_species = GBT_expect_species(gb_main, species_name);
930  if (!gb_species) {
931  error = GBS_global_string("%s (selected in %s hitlist)", GB_await_error(), listLocation);
932  }
933  }
934  else {
935  if (!acceptNone) {
936  error = GBS_global_string("Please select a %s species in %s hitlist", species_role, listLocation);
937  }
938  }
939  }
940 
941  mg_assert(implicated(!acceptNone, contradicted(error, gb_species)));
942  mg_assert(!(error && gb_species));
943 
944  return gb_species;
945  }
946 
947  GB_ERROR transferExistingOrNew(GBDATA *gb_src_item, GBDATA *gb_dst_item_container) {
948  GB_ERROR error = NULp;
949  const char *name = GBT_get_name(gb_src_item);
950 
951  if (!name) {
952  error = "unnamed item";
953  }
954  else {
955  GBDATA *gb_dst_item = GBT_find_species_rel_species_data(gb_dst_item_container, name);
956  if (gb_dst_item) { // found existing species
957  error = transferOne(gb_src_item, gb_dst_item, NULp); // use it as target
958  }
959  else { // not found
960  if (GB_have_error()) { // due to error
961  error = GB_await_error();
962  }
963  else { // otherwise create new species
964  error = transferOne(gb_src_item, NULp, gb_dst_item_container);
965  }
966  }
967  }
968  return error;
969  }
970 
971 protected:
972  static void markTarget(GBDATA *gb_dst_item) {
973  mg_assert(GB_is_ancestor_of(GLOBAL_gb_dst, gb_dst_item)); // only modify userflag of destination(!) database
974 
975  GB_write_flag(gb_dst_item, 1); // mark species
976  GB_raise_user_flag(gb_dst_item, GB_USERFLAG_QUERY); // put in search&query (destination) hitlist
977  }
978 
979 public:
980  virtual ~ScopedTransporter() {}
981 
982  static void set_query_to_update(QUERY::DbQuery *query) { query2update = query; }
983 
984  virtual GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container) = 0;
991  GB_ERROR transferAllIn(SpeciesXferScope scope, const char *progressTitle) {
994 
995  {
996  unsigned long scopeSize = 0;
997  switch (scope) {
998  case SXS_SELECTED_SPECIES: scopeSize = 1; break;
999  case SXS_LISTED_SPECIES: scopeSize = mg_count_queried(GLOBAL_gb_src); break;
1000  }
1001 
1002  arb_progress progress(progressTitle, scopeSize);
1003 
1004  GBDATA *gb_dst_species_container = GBT_get_species_data(GLOBAL_gb_dst);
1005  if (!error) {
1006  switch (scope) {
1007  case SXS_SELECTED_SPECIES: {
1008  GBDATA *gb_src_species = expect_selected_species(GLOBAL_gb_src, AWAR_SPECIES_SRC, "source", "left", error, false);
1009  GBDATA *gb_dst_species = expect_selected_species(GLOBAL_gb_dst, AWAR_SPECIES_DST, "target", "right", error, true);
1010 
1011  if (!error) {
1012  if (gb_dst_species) { // source and target explicitely selected
1013  error = transferOne(gb_src_species, gb_dst_species, NULp);
1014  }
1015  else {
1016  error = transferExistingOrNew(gb_src_species, gb_dst_species_container);
1017  }
1018  progress.inc_and_check_user_abort(error);
1019  }
1020  break;
1021  }
1022 
1023  case SXS_LISTED_SPECIES: {
1024  for (GBDATA *gb_src_species = GBT_first_species(GLOBAL_gb_src);
1025  gb_src_species && !error;
1026  gb_src_species = GBT_next_species(gb_src_species))
1027  {
1028  if (IS_QUERIED_SPECIES(gb_src_species)) {
1029  error = transferExistingOrNew(gb_src_species, gb_dst_species_container);
1030  if (error) { // mention name of species in error message:
1031  error = GBS_global_string("%s (species=%s)", error, GBT_get_name_or_description(gb_src_species));
1032  }
1033  progress.inc_and_check_user_abort(error);
1034  }
1035  }
1036  break;
1037  }
1038  }
1039  }
1040 
1041  if (error) progress.done();
1042  }
1043  error = GB_end_transaction(GLOBAL_gb_src, error);
1044  error = GB_end_transaction(GLOBAL_gb_dst, error);
1045 
1046  if (!error && query2update) DbQuery_update_list(query2update); // no need to update in case of error
1047 
1048  return error;
1049  }
1050 };
1051 
1052 QUERY::DbQuery *ScopedTransporter::query2update = NULp;
1053 
1054 using namespace FieldTransfer;
1055 
1057 
1059  MG_remapsPtr remaps;
1060 
1061 public:
1062  AdaptedAlignmentTransporter(MG_remapsPtr remaps_) : remaps(remaps_) {}
1063  bool shallCopyBefore() const OVERRIDE {
1064  return true; // ItemClonedByRuleSet::copyAlignments() shall be called b4 calling transport()
1065  }
1066  GB_ERROR transport(GBDATA *gb_src_item, GBDATA *gb_dst_item) const OVERRIDE {
1067  return MG_adaptAllCopiedAlignments(*remaps, gb_src_item, gb_dst_item);
1068  }
1069 };
1070 
1072  // this AlignmentTransporter simply does not transport anything
1073  bool shallCopyBefore() const OVERRIDE { return false; } // do not call copyAlignments() b4 calling transport()
1074  GB_ERROR transport(GBDATA *, GBDATA *) const OVERRIDE { return NULp; } // do not transport alignment data
1075 };
1076 
1077 
1078 
1080  RuleSetPtr fts;
1081  AlignmentTransporterPtr aliTransporter;
1082 
1083 public:
1085  fts(fts_),
1086  aliTransporter(transp)
1087  {}
1088  GB_ERROR transferOne(GBDATA *gb_src_item, GBDATA *gb_dst_item, GBDATA *gb_dst_item_container) OVERRIDE {
1089  mg_assert(fts.isSet());
1090  mg_assert(contradicted(gb_dst_item, gb_dst_item_container)); // exactly one of both shall be set
1091 
1092  GB_ERROR error = NULp;
1093  GBDATA *gb_transferred = NULp;
1094  {
1095  ItemClonedByRuleSet transfer(gb_src_item, CLONE_ITEM_SPECIES, fts,
1096  gb_dst_item ? CLONE_INTO_EXISTING : REAL_CLONE,
1097  gb_dst_item ? gb_dst_item : gb_dst_item_container,
1098  &*aliTransporter);
1099 
1100  if (transfer.has_error()) {
1101  error = transfer.get_error();
1102  }
1103  else {
1104  gb_transferred = transfer.get_clone();
1105  }
1106  }
1107 
1108  mg_assert(contradicted(error, gb_transferred));
1109  if (!error) markTarget(gb_transferred);
1110 
1111  return error;
1112  }
1113 };
1114 
1115 static void mg_xfer_via_fts(AW_root *aw_root, SpeciesXferScope scope, bool xfer_seq_data) {
1116  GB_ERROR error = NULp;
1117  const char *ftsname = XFER_getFullFTS(aw_root->awar(AWAR_SPECIES_XFER_FTS)->read_char_pntr());
1118 
1119  if (!ftsname[0]) {
1120  error = "No FTS selected";
1121  }
1122  else {
1123  ErrorOrRuleSetPtr loaded = RuleSet::loadFrom(ftsname);
1124  if (loaded.hasError()) {
1125  ARB_ERROR lerror = loaded.getError();
1126  error = lerror.deliver();
1127  }
1128  else {
1129  AlignmentTransporterPtr transport_ali;
1130  if (xfer_seq_data) {
1131  MG_remapsPtr remaps;
1132  {
1133  GB_transaction ta_src(GLOBAL_gb_src);
1134  GB_transaction ta_dst(GLOBAL_gb_dst);
1135  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
1136  // @@@ can MG_remaps report error? (e.g. if wrong SAI/species specified as reference)
1137  }
1138 
1139  transport_ali = new AdaptedAlignmentTransporter(remaps);
1140  }
1141  else {
1142  transport_ali = new DontTransportAlignment;
1143  }
1144 
1145  ViaFtsTransporter transporter(loaded.getValue(), transport_ali);
1146  error = transporter.transferAllIn(scope, "Transfer using FTS");
1147  }
1148  }
1149  aw_message_if(error);
1150 }
1151 
1153  void scanFields(StrArray& fields, FieldsToScan whatToScan) const OVERRIDE {
1154  if (whatToScan & SCAN_INPUT_FIELDS) {
1156  }
1157  if (whatToScan & SCAN_OUTPUT_FIELDS) {
1159  }
1160  }
1161 };
1162 
1164 
1165 static void MG_transfer_species(AW_window *aww) {
1166  AW_root *awr = aww->get_root();
1167 
1170 
1171  switch (type) {
1172  case SXT_WHOLE_SPECIES:
1173  switch (scope) {
1176  }
1177  break;
1178 
1179  case SXT_SINGLE_FIELD:
1181  break;
1182 
1183  case SXT_USING_FTS:
1184  case SXT_USING_FTS_SKIP_ALI: {
1185  bool xfer_seq_data = (type == SXT_USING_FTS);
1186  mg_xfer_via_fts(awr, scope, xfer_seq_data);
1187  break;
1188  }
1189  }
1190 }
1191 
1194  if (error) {
1195  aw_message(error);
1196  return NULp; // deny to open window before user has renamed species
1197  }
1198 
1201 
1203  aws->init(awr, "MERGE_TRANSFER_SPECIES", "TRANSFER SPECIES");
1204  aws->load_xfig("merge/species.fig");
1205 
1206  aws->at("close");
1207  aws->callback(AW_POPDOWN);
1208  aws->create_button("CLOSE", "CLOSE", "C");
1209 
1210  aws->at("help");
1211  aws->callback(makeHelpCallback("mg_species.hlp"));
1212  aws->create_button("HELP", "HELP", "H");
1213 
1215 
1216  {
1217  QUERY::query_spec awtqs(MG_species_selector[0]);
1218  aws->create_menu("Source-DB", "S");
1219 
1220  awtqs.gb_main = GLOBAL_gb_src;
1221  awtqs.gb_ref = GLOBAL_gb_dst;
1222  awtqs.expect_hit_in_ref_list = false;
1224  awtqs.tree_name = NULp; // no selected tree here -> can't use tree related ACI commands without specifying a tree
1225  awtqs.select_bit = GB_USERFLAG_QUERY;
1226  awtqs.ere_pos_fig = "ere1";
1227  awtqs.by_pos_fig = "by1";
1228  awtqs.qbox_pos_fig = "qbox1";
1229  awtqs.key_pos_fig = NULp;
1230  awtqs.query_pos_fig = "content1";
1231  awtqs.result_pos_fig = "result1";
1232  awtqs.count_pos_fig = "count1";
1233  awtqs.do_query_pos_fig = "doquery1";
1234  awtqs.config_pos_fig = "doconfig1";
1235  awtqs.do_mark_pos_fig = NULp;
1236  awtqs.do_unmark_pos_fig = NULp;
1237  awtqs.do_delete_pos_fig = "dodelete1";
1238  awtqs.do_set_pos_fig = "doset1";
1239  awtqs.do_refresh_pos_fig = "dorefresh1";
1240  awtqs.open_parser_pos_fig = "openparser1";
1241  awtqs.use_menu = 1;
1242 
1243  create_query_box(aws, &awtqs, "db1");
1244 
1245  DbScanner *scanner = DbScanner::create(GLOBAL_gb_src, "merge_spec1", aws, "box1", NULp, NULp, DB_SCANNER, NULp, awtqs.get_queried_itemtype());
1246  scanner_src = scanner;
1247  aws->get_root()->awar(AWAR_SPECIES_SRC)->add_callback(makeRootCallback(MG_map_species, SRC_DB));
1248  }
1249  {
1250  QUERY::query_spec awtqs(MG_species_selector[1]);
1251  aws->create_menu("Target-DB", "T");
1252 
1253  awtqs.gb_main = GLOBAL_gb_dst;
1254  awtqs.gb_ref = GLOBAL_gb_src;
1255  awtqs.expect_hit_in_ref_list = true;
1257  awtqs.select_bit = GB_USERFLAG_QUERY;
1258  awtqs.ere_pos_fig = "ere2";
1259  awtqs.by_pos_fig = "by2";
1260  awtqs.qbox_pos_fig = "qbox2";
1261  awtqs.key_pos_fig = NULp;
1262  awtqs.query_pos_fig = "content2";
1263  awtqs.result_pos_fig = "result2";
1264  awtqs.count_pos_fig = "count2";
1265  awtqs.do_query_pos_fig = "doquery2";
1266  awtqs.config_pos_fig = "doconfig2";
1267  awtqs.do_mark_pos_fig = NULp;
1268  awtqs.do_unmark_pos_fig = NULp;
1269  awtqs.do_delete_pos_fig = "dodelete2";
1270  awtqs.do_set_pos_fig = "doset2";
1271  awtqs.do_refresh_pos_fig = "dorefresh2";
1272  awtqs.open_parser_pos_fig = "openparser2";
1273  awtqs.use_menu = 1;
1274 
1276 
1277  DbScanner *scanner = DbScanner::create(GLOBAL_gb_dst, "merge_spec2", aws, "box2", NULp, NULp, DB_SCANNER, NULp, awtqs.get_queried_itemtype());
1278  scanner_dst = scanner;
1279  aws->get_root()->awar(AWAR_SPECIES_DST)->add_callback(makeRootCallback(MG_map_species, DST_DB));
1280  }
1281 
1282  // ---------------------
1283  // middle area
1284 
1285  // top icon
1286  aws->button_length(0);
1287  aws->at("icon");
1288  aws->callback(makeHelpCallback("mg_species.hlp"));
1289  aws->create_button("HELP_MERGE", "#merge/icon.xpm");
1290 
1291  // adapt alignments
1292  {
1293  if (dst_is_new) {
1294  aws->sens_mask(AWM_DISABLED); // if dest DB is new = > adaption impossible
1295  awr->awar(AWAR_REMAP_ENABLE)->write_int(0); // disable adaption
1296  }
1297 
1298  aws->at("adapt");
1300 
1301  aws->at("reference");
1303 
1304  aws->at("pres_sel");
1306  aws->create_autosize_button("SELECT", "SELECT", "S");
1307 
1308  aws->sens_mask(AWM_ALL);
1309  }
1310 
1311  // transfer options:
1312  aws->at("xferType");
1314  aws->insert_option("whole species", "w", SXT_WHOLE_SPECIES);
1315  aws->insert_option("single field", "s", SXT_SINGLE_FIELD);
1316  aws->insert_option("using FTS (with seq)", "F", SXT_USING_FTS);
1317  aws->insert_option("using FTS (w/o seq)", "o", SXT_USING_FTS_SKIP_ALI);
1318  aws->update_option_menu();
1319 
1320  aws->at("fts");
1321  aws->callback(makeWindowCallback(XFER_select_RuleSet, AWAR_SPECIES_XFER_FTS, static_cast<AvailableFieldScanner*>(&fieldScanner)));
1322  aws->create_button("SELECT_FTS", AWAR_SPECIES_XFER_FTS);
1323 
1324  aws->at("xferWhat");
1326  aws->insert_option("listed species", "l", SXS_LISTED_SPECIES);
1327  aws->insert_option("selected species", "s", SXS_SELECTED_SPECIES);
1328  aws->update_option_menu();
1329 
1330  {
1331  aws->shadow_width(3);
1332 
1333  aws->at("transfer");
1335  aws->create_button("TRANSFER", "Transfer species");
1336 
1337  aws->shadow_width(1);
1338  }
1339 
1340  aws->create_menu("Source->Target", "g");
1341  aws->insert_menu_topic("compare_field_of_listed", "Compare a field of listed species ...", "C", "checkfield.hlp", AWM_ALL, create_mg_check_fields_window);
1342  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);
1343  aws->sep______________();
1344  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);
1345 
1346 
1347  return aws;
1348 }
1349 
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2516
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:2144
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:991
GB_TYPES type
void button_length(int length)
Definition: AW_at.cxx:283
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:902
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:723
#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:1385
bool fieldContainsAlignment(const char *field)
Definition: MG_species.cxx:353
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: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:2549
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:316
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:842
void GB_end_transaction_show_error(GBDATA *gbd, GB_ERROR error, void(*error_handler)(GB_ERROR))
Definition: arbdb.cxx:2572
long read_int() const
Definition: AW_awar.cxx:187
bool hasError() const
Definition: ErrorOrType.h:48
TYPE getValue() const
Definition: ErrorOrType.h:56
DbQuery * create_query_box(AW_window *aws, query_spec *awtqs, const char *query_id)
Definition: db_query.cxx:2346
ViaFtsTransporter(RuleSetPtr fts_, AlignmentTransporterPtr transp)
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:972
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:125
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:619
GB_HASH * GBT_create_species_hash(GBDATA *gb_main)
Definition: adhashtools.cxx:36
void cat(const char *from)
Definition: arb_strbuf.h:158
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)
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:1720
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:1904
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:2743
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:1827
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:1641
GB_ERROR deliver() const
Definition: arb_error.h:114
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:2880
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: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:1742
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: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: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:878
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
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: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: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
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
#define AWAR_TAG_SRC
Definition: MG_species.cxx:35
static void set_query_to_update(QUERY::DbQuery *query)
Definition: MG_species.cxx:982
void MG_create_species_awars(AW_root *aw_root, AW_default aw_def)
Definition: MG_species.cxx:65
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:2761
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:885
#define CHANGE_KEY_PATH
Definition: arbdbt.h:86
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:903
GB_ERROR GB_copy_dropMarksAndTempstate(GBDATA *dest, GBDATA *source)
Definition: arbdb.cxx:2155
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: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: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: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:450
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:51
bool shallCopyBefore() const OVERRIDE
virtual ~ScopedTransporter()
Definition: MG_species.cxx:980
#define FALLTHROUGH
Definition: cxxforward.h:110
#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:441
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:893
#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: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: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:904
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