| 1 | // ======================================================================================= |
|---|
| 2 | // |
|---|
| 3 | // File : NT_concatenate.cxx |
|---|
| 4 | // Purpose : 1.Concatenatenation of sequences or alignments |
|---|
| 5 | // 2.Merging the fields of similar species and creating a new species |
|---|
| 6 | // Author : Yadhu Kumar |
|---|
| 7 | // web site : http://www.arb-home.de/ |
|---|
| 8 | // |
|---|
| 9 | // Copyright Department of Microbiology (Technical University Munich) |
|---|
| 10 | // |
|---|
| 11 | // ======================================================================================= |
|---|
| 12 | |
|---|
| 13 | #include "NT_local.h" |
|---|
| 14 | |
|---|
| 15 | #include <items.h> |
|---|
| 16 | #include <item_sel_list.h> |
|---|
| 17 | #include <awt_sel_boxes.hxx> |
|---|
| 18 | #include <AW_rename.hxx> |
|---|
| 19 | #include <aw_question.hxx> |
|---|
| 20 | #include <aw_awar.hxx> |
|---|
| 21 | #include <aw_msg.hxx> |
|---|
| 22 | #include <aw_root.hxx> |
|---|
| 23 | #include <arb_progress.h> |
|---|
| 24 | #include <arb_strbuf.h> |
|---|
| 25 | #include <arb_strarray.h> |
|---|
| 26 | #include <awt_modules.hxx> |
|---|
| 27 | #include <arb_global_defs.h> |
|---|
| 28 | |
|---|
| 29 | using namespace std; |
|---|
| 30 | |
|---|
| 31 | #define AWAR_CON_SEQUENCE_TYPE "tmp/concat/sequence_type" |
|---|
| 32 | #define AWAR_CON_NEW_ALIGNMENT_NAME "tmp/concat/new_alignment_name" |
|---|
| 33 | #define AWAR_CON_ALIGNMENT_SEPARATOR "tmp/concat/alignment_separator" |
|---|
| 34 | #define AWAR_CON_SELECTED_ALI "tmp/concat/database_alignments" |
|---|
| 35 | #define AWAR_CON_MERGE_FIELD "tmp/concat/merge_field" |
|---|
| 36 | #define AWAR_CON_STORE_SIM_SP_NO "tmp/concat/store_sim_sp_no" |
|---|
| 37 | |
|---|
| 38 | #define AWAR_CON_ALLOW_OVERWRITE_ALI "tmp/concat/overwrite" |
|---|
| 39 | #define AWAR_CON_INSGAPS_FOR_MISS_ALIS "tmp/concat/insgaps" |
|---|
| 40 | |
|---|
| 41 | #define MOVE_DOWN 0 |
|---|
| 42 | #define MOVE_UP 1 |
|---|
| 43 | |
|---|
| 44 | struct SpeciesConcatenateList { |
|---|
| 45 | GBDATA *species; |
|---|
| 46 | char *species_name; |
|---|
| 47 | |
|---|
| 48 | SpeciesConcatenateList *next; |
|---|
| 49 | }; |
|---|
| 50 | |
|---|
| 51 | // --------------------------creating and initializing AWARS---------------------------------------- |
|---|
| 52 | void NT_createConcatenationAwars(AW_root *aw_root, AW_default aw_def, GBDATA *gb_main) { |
|---|
| 53 | GB_transaction ta(gb_main); |
|---|
| 54 | |
|---|
| 55 | char *ali_default = GBT_get_default_alignment(gb_main); |
|---|
| 56 | char *ali_type = NULp; |
|---|
| 57 | |
|---|
| 58 | if (ali_default) { |
|---|
| 59 | ali_type = GBT_get_alignment_type_string(gb_main, ali_default); |
|---|
| 60 | if (!ali_type) { |
|---|
| 61 | // Note: this message will appear during startup (i.e. stick to general statement here!) |
|---|
| 62 | aw_message(GBS_global_string("Failed to detect type of default alignment (%s)\n" |
|---|
| 63 | "(Reason: %s)", ali_default, GB_await_error())); |
|---|
| 64 | } |
|---|
| 65 | } |
|---|
| 66 | if (!ali_type) ali_type = ARB_strdup("rna"); |
|---|
| 67 | |
|---|
| 68 | aw_root->awar_string(AWAR_CON_SEQUENCE_TYPE, ali_type, aw_def); |
|---|
| 69 | aw_root->awar_string(AWAR_CON_NEW_ALIGNMENT_NAME, "ali_concat", aw_def)->set_srt(SRT_AUTOCORRECT_ALINAME); |
|---|
| 70 | aw_root->awar_string(AWAR_CON_ALIGNMENT_SEPARATOR, "XXX", aw_def); |
|---|
| 71 | aw_root->awar_string(AWAR_CON_SELECTED_ALI, "", aw_def); |
|---|
| 72 | aw_root->awar_string(AWAR_CON_MERGE_FIELD, "full_name", aw_def); |
|---|
| 73 | aw_root->awar_string(AWAR_CON_STORE_SIM_SP_NO, "merged_species", aw_def); |
|---|
| 74 | |
|---|
| 75 | aw_root->awar_int(AWAR_CON_ALLOW_OVERWRITE_ALI, 0, aw_def); |
|---|
| 76 | aw_root->awar_int(AWAR_CON_INSGAPS_FOR_MISS_ALIS, 1, aw_def); |
|---|
| 77 | |
|---|
| 78 | free(ali_type); |
|---|
| 79 | free(ali_default); |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | // ------------------------Selecting alignments from the database for concatenation---------------------- |
|---|
| 83 | |
|---|
| 84 | inline char *get_alitype_eval(AW_root *aw_root) { |
|---|
| 85 | return GBS_global_string_copy("%s=", aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->read_char_pntr()); |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | static void alitype_changed_cb(AW_root *aw_root, AW_DB_selection *db_sel) { |
|---|
| 89 | char *ali_type = get_alitype_eval(aw_root); |
|---|
| 90 | awt_reconfigure_ALI_selection_list(db_sel, ali_type); |
|---|
| 91 | free(ali_type); |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | static AW_DB_selection* createSelectionList(GBDATA *gb_main, AW_window *aws, const char *awarName) { |
|---|
| 95 | |
|---|
| 96 | #ifdef DEBUG |
|---|
| 97 | static bool ran=false; |
|---|
| 98 | nt_assert(!ran); |
|---|
| 99 | ran=true; // prevents calling this function for the second time |
|---|
| 100 | #endif |
|---|
| 101 | |
|---|
| 102 | AW_root *aw_root = aws->get_root(); |
|---|
| 103 | char *ali_type = get_alitype_eval(aw_root); |
|---|
| 104 | AW_DB_selection *db_sel = awt_create_ALI_selection_list(gb_main, aws, awarName, ali_type); |
|---|
| 105 | |
|---|
| 106 | free(ali_type); |
|---|
| 107 | return db_sel; |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | // ---------- Create SAI to display alignments that were concatenated -------------- |
|---|
| 111 | |
|---|
| 112 | static GB_ERROR create_concatInfo_SAI(GBDATA *gb_main, const char *new_ali_name, const char *ali_separator, const StrArray& ali_names) { |
|---|
| 113 | GB_ERROR error = NULp; |
|---|
| 114 | GBDATA *gb_extended = GBT_find_or_create_SAI(gb_main, "ConcatInfo"); |
|---|
| 115 | |
|---|
| 116 | if (!gb_extended) error = GB_await_error(); |
|---|
| 117 | else { |
|---|
| 118 | GBDATA *gb_data = GBT_add_data(gb_extended, new_ali_name, "data", GB_STRING); |
|---|
| 119 | |
|---|
| 120 | if (!gb_data) { |
|---|
| 121 | error = GB_await_error(); |
|---|
| 122 | } |
|---|
| 123 | else { |
|---|
| 124 | int new_ali_length = GBT_get_alignment_len(gb_main, new_ali_name); |
|---|
| 125 | int sep_len = strlen(ali_separator); |
|---|
| 126 | |
|---|
| 127 | char *info = ARB_alloc<char>(new_ali_length+1); |
|---|
| 128 | memset(info, '=', new_ali_length); |
|---|
| 129 | |
|---|
| 130 | int offset = 0; |
|---|
| 131 | int last_ali_idx = ali_names.size()-1; |
|---|
| 132 | |
|---|
| 133 | for (int a = 0; a <= last_ali_idx; ++a) { |
|---|
| 134 | const char *ali = ali_names[a]; |
|---|
| 135 | int ali_len = GBT_get_alignment_len(gb_main, ali); |
|---|
| 136 | int ali_str_len = strlen(ali); |
|---|
| 137 | |
|---|
| 138 | char *my_info = info+offset; |
|---|
| 139 | |
|---|
| 140 | int half_ali_len = ali_len/2; |
|---|
| 141 | for (int i = 0; i<5; ++i) { |
|---|
| 142 | if (i<half_ali_len) { |
|---|
| 143 | my_info[i] = '<'; |
|---|
| 144 | my_info[ali_len-i-1] = '>'; |
|---|
| 145 | } |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | if (ali_str_len<ali_len) { |
|---|
| 149 | int namepos = half_ali_len - ali_str_len/2; |
|---|
| 150 | memcpy(my_info+namepos, ali, ali_str_len); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | offset += ali_len; |
|---|
| 154 | if (a != last_ali_idx) { |
|---|
| 155 | memcpy(info+offset, ali_separator, sep_len); |
|---|
| 156 | offset += sep_len; |
|---|
| 157 | } |
|---|
| 158 | } |
|---|
| 159 | |
|---|
| 160 | nt_assert(offset == new_ali_length); // wrong alignment length! |
|---|
| 161 | info[new_ali_length] = 0; |
|---|
| 162 | |
|---|
| 163 | if (!error) error = GB_write_string(gb_data, info); |
|---|
| 164 | free(info); |
|---|
| 165 | } |
|---|
| 166 | } |
|---|
| 167 | return error; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | // ---------------------------------------- Concatenation function ---------------------------------- |
|---|
| 171 | static void concatenateAlignments(AW_window *aws, AW_selection *selected_alis) { |
|---|
| 172 | nt_assert(selected_alis); |
|---|
| 173 | |
|---|
| 174 | GB_push_transaction(GLOBAL.gb_main); |
|---|
| 175 | |
|---|
| 176 | long marked_species = GBT_count_marked_species(GLOBAL.gb_main); |
|---|
| 177 | AW_root *aw_root = aws->get_root(); |
|---|
| 178 | char *new_ali_name = aw_root->awar(AWAR_CON_NEW_ALIGNMENT_NAME)->read_string(); |
|---|
| 179 | GB_ERROR error = GBT_check_alignment_name(new_ali_name); |
|---|
| 180 | |
|---|
| 181 | StrArray ali_names; |
|---|
| 182 | selected_alis->get_values(ali_names); |
|---|
| 183 | |
|---|
| 184 | arb_progress progress("Concatenating alignments", marked_species); |
|---|
| 185 | size_t ali_count = ali_names.size(); |
|---|
| 186 | |
|---|
| 187 | if (!error && ali_count<2) { |
|---|
| 188 | error = "Not enough alignments selected for concatenation (need at least 2)"; |
|---|
| 189 | } |
|---|
| 190 | if (!error) { |
|---|
| 191 | int found[ali_count], missing[ali_count], ali_length[ali_count]; |
|---|
| 192 | |
|---|
| 193 | for (size_t a = 0; a<ali_count; a++) { |
|---|
| 194 | found[a] = 0; |
|---|
| 195 | missing[a] = 0; |
|---|
| 196 | ali_length[a] = GBT_get_alignment_len(GLOBAL.gb_main, ali_names[a]); |
|---|
| 197 | |
|---|
| 198 | if (strcmp(ali_names[a], new_ali_name) == 0) { |
|---|
| 199 | error = "Target alignment may not be one of the source alignments"; |
|---|
| 200 | } |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | if (!error) { |
|---|
| 204 | char *ali_separator = aw_root->awar(AWAR_CON_ALIGNMENT_SEPARATOR)->read_string(); |
|---|
| 205 | const int sep_len = strlen(ali_separator); |
|---|
| 206 | |
|---|
| 207 | long new_alignment_len = (ali_count-1)*sep_len; |
|---|
| 208 | for (size_t a = 0; a<ali_count; ++a) { // LOOP_VECTORIZED |
|---|
| 209 | new_alignment_len += ali_length[a]; |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | GBDATA *gb_presets = GBT_get_presets(GLOBAL.gb_main); |
|---|
| 213 | GBDATA *gb_alignment_exists = GB_find_string(gb_presets, "alignment_name", new_ali_name, GB_IGNORE_CASE, SEARCH_GRANDCHILD); |
|---|
| 214 | GBDATA *gb_new_alignment = NULp; |
|---|
| 215 | char *seq_type = aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->read_string(); |
|---|
| 216 | |
|---|
| 217 | if (gb_alignment_exists) { |
|---|
| 218 | // target alignment exists |
|---|
| 219 | if (aw_root->awar(AWAR_CON_ALLOW_OVERWRITE_ALI)->read_int()) { // allow overwrite |
|---|
| 220 | gb_new_alignment = GBT_get_alignment(GLOBAL.gb_main, new_ali_name); |
|---|
| 221 | if (!gb_new_alignment) error = GB_await_error(); |
|---|
| 222 | } |
|---|
| 223 | else { |
|---|
| 224 | error = GBS_global_string("Target alignment '%s' already exists\n(check overwrite-toggle if you really want to overwrite)", new_ali_name); |
|---|
| 225 | } |
|---|
| 226 | } |
|---|
| 227 | else { |
|---|
| 228 | // create new target alignment |
|---|
| 229 | gb_new_alignment = GBT_create_alignment(GLOBAL.gb_main, new_ali_name, new_alignment_len, 0, 0, seq_type); |
|---|
| 230 | if (!gb_new_alignment) error = GB_await_error(); |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | if (!error) { |
|---|
| 234 | AW_repeated_question ask_about_missing_alignment; |
|---|
| 235 | bool insertGaps = aw_root->awar(AWAR_CON_INSGAPS_FOR_MISS_ALIS)->read_int(); |
|---|
| 236 | |
|---|
| 237 | for (GBDATA *gb_species = GBT_first_marked_species(GLOBAL.gb_main); |
|---|
| 238 | gb_species && !error; |
|---|
| 239 | gb_species = GBT_next_marked_species(gb_species)) |
|---|
| 240 | { |
|---|
| 241 | GBS_strstruct concat_seq(new_alignment_len+1); |
|---|
| 242 | int data_inserted = 0; |
|---|
| 243 | |
|---|
| 244 | for (size_t a = 0; a<ali_count; ++a) { |
|---|
| 245 | if (a) concat_seq.cat(ali_separator); |
|---|
| 246 | |
|---|
| 247 | GBDATA *gb_seq_data = GBT_find_sequence(gb_species, ali_names[a]); |
|---|
| 248 | if (gb_seq_data) { // found data |
|---|
| 249 | const char *seq_data = GB_read_char_pntr(gb_seq_data); |
|---|
| 250 | concat_seq.cat(seq_data); |
|---|
| 251 | ++found[a]; |
|---|
| 252 | ++data_inserted; |
|---|
| 253 | } |
|---|
| 254 | else { // missing data |
|---|
| 255 | if (insertGaps) concat_seq.nput('.', ali_length[a]); |
|---|
| 256 | ++missing[a]; |
|---|
| 257 | } |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | if (!data_inserted) { |
|---|
| 261 | error = GBS_global_string("None of the source alignments had data for species '%s'", GBT_read_name(gb_species)); |
|---|
| 262 | } |
|---|
| 263 | else { |
|---|
| 264 | GBDATA *gb_data = GBT_add_data(gb_species, new_ali_name, "data", GB_STRING); |
|---|
| 265 | GB_write_string(gb_data, concat_seq.get_data()); |
|---|
| 266 | } |
|---|
| 267 | progress.inc_and_check_user_abort(error); |
|---|
| 268 | } |
|---|
| 269 | |
|---|
| 270 | if (!error) { |
|---|
| 271 | // ............. print missing alignments........... |
|---|
| 272 | aw_message(GBS_global_string("Concatenation of alignments was performed for %ld species.", marked_species)); |
|---|
| 273 | for (size_t a = 0; a<ali_count; ++a) { |
|---|
| 274 | aw_message(GBS_global_string("%s: was found in %d species and missing in %d species.", ali_names[a], found[a], missing[a])); |
|---|
| 275 | } |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | if (!error) error = GBT_check_data(GLOBAL.gb_main, new_ali_name); // update alignment info (otherwise create_concatInfo_SAI fails when overwriting an alignment) |
|---|
| 279 | if (!error) error = create_concatInfo_SAI(GLOBAL.gb_main, new_ali_name, ali_separator, ali_names); |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | free(seq_type); |
|---|
| 283 | free(ali_separator); |
|---|
| 284 | } |
|---|
| 285 | } |
|---|
| 286 | |
|---|
| 287 | if (!error) { |
|---|
| 288 | char *nfield = GBS_global_string_copy("%s/data", new_ali_name); |
|---|
| 289 | error = GBT_add_new_changekey(GLOBAL.gb_main, nfield, GB_STRING); |
|---|
| 290 | free(nfield); |
|---|
| 291 | } |
|---|
| 292 | else { |
|---|
| 293 | progress.done(); |
|---|
| 294 | } |
|---|
| 295 | GB_end_transaction_show_error(GLOBAL.gb_main, error, aw_message); |
|---|
| 296 | free(new_ali_name); |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | static void addSpeciesToConcatenateList(SpeciesConcatenateList **sclp, GB_CSTR species_name) { |
|---|
| 300 | |
|---|
| 301 | GBDATA *gb_species_data = GBT_get_species_data(GLOBAL.gb_main); |
|---|
| 302 | GBDATA *gb_species = GBT_find_species_rel_species_data(gb_species_data, species_name); |
|---|
| 303 | |
|---|
| 304 | if (gb_species) { |
|---|
| 305 | SpeciesConcatenateList *scl = new SpeciesConcatenateList; |
|---|
| 306 | |
|---|
| 307 | scl->species = gb_species; |
|---|
| 308 | scl->species_name = ARB_strdup(species_name); |
|---|
| 309 | scl->next = *sclp; |
|---|
| 310 | *sclp = scl; |
|---|
| 311 | } |
|---|
| 312 | } |
|---|
| 313 | |
|---|
| 314 | static void freeSpeciesConcatenateList(SpeciesConcatenateList *scl) { |
|---|
| 315 | while (scl) { |
|---|
| 316 | SpeciesConcatenateList *next = scl->next; |
|---|
| 317 | free(scl->species_name); |
|---|
| 318 | delete scl; |
|---|
| 319 | scl = next; |
|---|
| 320 | } |
|---|
| 321 | } |
|---|
| 322 | |
|---|
| 323 | static GB_ERROR checkAndMergeFields(GBDATA *gb_new_species, GB_ERROR error, SpeciesConcatenateList *scl) { |
|---|
| 324 | |
|---|
| 325 | char *doneFields = ARB_strdup(";name;"); // all fields which are already merged |
|---|
| 326 | int doneLen = strlen(doneFields); |
|---|
| 327 | SpeciesConcatenateList *sl = scl; |
|---|
| 328 | int sl_length = 0; while (scl) { sl_length++; scl=scl->next; } // counting no. of similar species stored in the list |
|---|
| 329 | int *fieldStat = new int[sl_length]; // 0 = not used yet ; -1 = doesn't have field ; 1..n = field content (same number means same content) |
|---|
| 330 | |
|---|
| 331 | while (sl && !error) { // with all species do.. |
|---|
| 332 | char *newFields = GB_get_subfields(sl->species); |
|---|
| 333 | char *fieldStart = newFields; // points to ; before next field |
|---|
| 334 | |
|---|
| 335 | while (fieldStart[1] && !error) { // with all subfields of the species do.. |
|---|
| 336 | char *fieldEnd = strchr(fieldStart+1, ';'); |
|---|
| 337 | nt_assert(fieldEnd); |
|---|
| 338 | char behind = fieldEnd[1]; fieldEnd[1] = 0; |
|---|
| 339 | |
|---|
| 340 | if (!strstr(doneFields, fieldStart)) { // field is not merged yet |
|---|
| 341 | char *fieldName = fieldStart+1; |
|---|
| 342 | int fieldLen = int(fieldEnd-fieldName); |
|---|
| 343 | |
|---|
| 344 | nt_assert(fieldEnd[0]==';'); |
|---|
| 345 | fieldEnd[0] = 0; |
|---|
| 346 | |
|---|
| 347 | GBDATA *gb_field = GB_search(sl->species, fieldName, GB_FIND); // field does to exist (it was found before) |
|---|
| 348 | GB_TYPES type = GB_read_type(gb_field); |
|---|
| 349 | |
|---|
| 350 | if (type==GB_STRING) { // we only merge string fields |
|---|
| 351 | int i; int doneSpecies = 0; int nextStat = 1; |
|---|
| 352 | |
|---|
| 353 | for (i=0; i<sl_length; i++) { fieldStat[i] = 0; } // clear field status |
|---|
| 354 | |
|---|
| 355 | while (doneSpecies<sl_length) { // since all species in list were handled |
|---|
| 356 | SpeciesConcatenateList *sl2 = sl; |
|---|
| 357 | i = 0; |
|---|
| 358 | |
|---|
| 359 | while (sl2) { |
|---|
| 360 | if (fieldStat[i]==0) { |
|---|
| 361 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 362 | if (gb_field) { |
|---|
| 363 | char *content = GB_read_as_string(gb_field); |
|---|
| 364 | SpeciesConcatenateList *sl3 = sl2->next; |
|---|
| 365 | fieldStat[i] = nextStat; |
|---|
| 366 | int j = i+1; doneSpecies++; |
|---|
| 367 | |
|---|
| 368 | while (sl3) { |
|---|
| 369 | if (fieldStat[j]==0) { |
|---|
| 370 | gb_field = GB_search(sl3->species, fieldName, GB_FIND); |
|---|
| 371 | if (gb_field) { |
|---|
| 372 | char *content2 = GB_read_as_string(gb_field); |
|---|
| 373 | if (strcmp(content, content2)==0) { // if contents are the same, they get the same status |
|---|
| 374 | fieldStat[j] = nextStat; |
|---|
| 375 | doneSpecies++; |
|---|
| 376 | } |
|---|
| 377 | free(content2); |
|---|
| 378 | } |
|---|
| 379 | else { |
|---|
| 380 | fieldStat[j] = -1; |
|---|
| 381 | doneSpecies++; |
|---|
| 382 | } |
|---|
| 383 | } |
|---|
| 384 | sl3 = sl3->next; j++; |
|---|
| 385 | } |
|---|
| 386 | free(content); nextStat++; |
|---|
| 387 | } |
|---|
| 388 | else { |
|---|
| 389 | fieldStat[i] = -1; // field does not exist here |
|---|
| 390 | doneSpecies++; |
|---|
| 391 | } |
|---|
| 392 | } |
|---|
| 393 | sl2 = sl2->next; i++; |
|---|
| 394 | } |
|---|
| 395 | if (!sl2) break; |
|---|
| 396 | } |
|---|
| 397 | nt_assert(nextStat!=1); // this would mean that none of the species contained the field |
|---|
| 398 | { |
|---|
| 399 | char *new_content = NULp; |
|---|
| 400 | int new_content_len = 0; // @@@ useless (0 where used; unused otherwise) |
|---|
| 401 | |
|---|
| 402 | if (nextStat==2) { // all species contain same field content or do not have the field |
|---|
| 403 | SpeciesConcatenateList *sl2 = sl; |
|---|
| 404 | while (sl2) { |
|---|
| 405 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 406 | if (gb_field) { |
|---|
| 407 | new_content = GB_read_as_string(gb_field); |
|---|
| 408 | new_content_len = strlen(new_content); |
|---|
| 409 | break; |
|---|
| 410 | } |
|---|
| 411 | sl2 = sl2->next; |
|---|
| 412 | } |
|---|
| 413 | } |
|---|
| 414 | else { // different field contents |
|---|
| 415 | int actualStat; |
|---|
| 416 | for (actualStat=1; actualStat<nextStat; actualStat++) { |
|---|
| 417 | SpeciesConcatenateList *sl2 = sl; |
|---|
| 418 | |
|---|
| 419 | int names_len = 1; // open bracket |
|---|
| 420 | char *content = NULp; |
|---|
| 421 | i = 0; |
|---|
| 422 | |
|---|
| 423 | while (sl2) { |
|---|
| 424 | if (fieldStat[i]==actualStat) { |
|---|
| 425 | names_len += strlen(sl2->species_name)+1; |
|---|
| 426 | if (!content) { |
|---|
| 427 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 428 | nt_assert(gb_field); |
|---|
| 429 | content = GB_read_as_string(gb_field); |
|---|
| 430 | } |
|---|
| 431 | } |
|---|
| 432 | sl2 = sl2->next; i++; |
|---|
| 433 | } |
|---|
| 434 | nt_assert(content); |
|---|
| 435 | int add_len = names_len+1+strlen(content); |
|---|
| 436 | char *whole = ARB_alloc<char>(new_content_len+1+add_len+1); |
|---|
| 437 | nt_assert(whole); |
|---|
| 438 | char *add = new_content ? whole+sprintf(whole, "%s ", new_content) : whole; |
|---|
| 439 | sl2 = sl; i = 0; |
|---|
| 440 | int first = 1; |
|---|
| 441 | while (sl2) { |
|---|
| 442 | if (fieldStat[i]==actualStat) { |
|---|
| 443 | add += sprintf(add, "%c%s", first ? '{' : ';', sl2->species_name); |
|---|
| 444 | first = 0; |
|---|
| 445 | } |
|---|
| 446 | sl2 = sl2->next; i++; |
|---|
| 447 | } |
|---|
| 448 | add += sprintf(add, "} %s", content); |
|---|
| 449 | |
|---|
| 450 | free(content); |
|---|
| 451 | freeset(new_content, whole); |
|---|
| 452 | new_content_len = strlen(new_content); // cppcheck-suppress deallocuse |
|---|
| 453 | } |
|---|
| 454 | } |
|---|
| 455 | |
|---|
| 456 | if (new_content) { |
|---|
| 457 | error = GBT_write_string(gb_new_species, fieldName, new_content); |
|---|
| 458 | free(new_content); |
|---|
| 459 | } |
|---|
| 460 | } |
|---|
| 461 | } |
|---|
| 462 | |
|---|
| 463 | // mark field as done: |
|---|
| 464 | char *new_doneFields = ARB_alloc<char>(doneLen+fieldLen+1+1); |
|---|
| 465 | sprintf(new_doneFields, "%s%s;", doneFields, fieldName); |
|---|
| 466 | doneLen += fieldLen+1; |
|---|
| 467 | freeset(doneFields, new_doneFields); |
|---|
| 468 | fieldEnd[0] = ';'; |
|---|
| 469 | } |
|---|
| 470 | fieldEnd[1] = behind; |
|---|
| 471 | fieldStart = fieldEnd; |
|---|
| 472 | } |
|---|
| 473 | free(newFields); |
|---|
| 474 | sl = sl->next; |
|---|
| 475 | } |
|---|
| 476 | free(doneFields); |
|---|
| 477 | delete [] fieldStat; |
|---|
| 478 | |
|---|
| 479 | return error; |
|---|
| 480 | } |
|---|
| 481 | |
|---|
| 482 | static GBDATA *concatenateFieldsCreateNewSpecies(AW_window *, GBDATA *gb_species, SpeciesConcatenateList *scl) { |
|---|
| 483 | GB_push_transaction(GLOBAL.gb_main); |
|---|
| 484 | |
|---|
| 485 | GB_ERROR error = NULp; |
|---|
| 486 | GBDATA *gb_species_data = GBT_get_species_data(GLOBAL.gb_main); |
|---|
| 487 | |
|---|
| 488 | // data needed for name generation |
|---|
| 489 | char *full_name = NULp; |
|---|
| 490 | char *acc = NULp; |
|---|
| 491 | |
|---|
| 492 | // --------------------getting the species related data -------------------- |
|---|
| 493 | |
|---|
| 494 | GBDATA *gb_new_species = NULp; |
|---|
| 495 | |
|---|
| 496 | if (!error) { |
|---|
| 497 | // copy species to create a new species |
|---|
| 498 | gb_new_species = GB_create_container(gb_species_data, "species"); |
|---|
| 499 | error = gb_new_species ? GB_copy_dropProtectMarksAndTempstate(gb_new_species, gb_species) : GB_await_error(); |
|---|
| 500 | |
|---|
| 501 | if (!error) { // write dummy-name (real name written below) |
|---|
| 502 | error = GBT_write_string(gb_new_species, "name", "$currcat$"); |
|---|
| 503 | } |
|---|
| 504 | } |
|---|
| 505 | |
|---|
| 506 | if (!error) { // copy full name |
|---|
| 507 | full_name = GBT_read_string(gb_species, "full_name"); |
|---|
| 508 | if (!full_name) error = GB_await_error(); |
|---|
| 509 | else error = GBT_write_string(gb_new_species, "full_name", full_name); |
|---|
| 510 | } |
|---|
| 511 | |
|---|
| 512 | if (!error) { |
|---|
| 513 | ConstStrArray ali_names; |
|---|
| 514 | GBT_get_alignment_names(ali_names, GLOBAL.gb_main); |
|---|
| 515 | |
|---|
| 516 | long id = 0; |
|---|
| 517 | for (SpeciesConcatenateList *speciesList = scl; speciesList; speciesList = speciesList->next) { |
|---|
| 518 | for (int no_of_alignments = 0; ali_names[no_of_alignments]; no_of_alignments++) { |
|---|
| 519 | GBDATA *gb_seq_data = GBT_find_sequence(speciesList->species, ali_names[no_of_alignments]); |
|---|
| 520 | if (gb_seq_data) { |
|---|
| 521 | const char *seq_data = GB_read_char_pntr(gb_seq_data); |
|---|
| 522 | GBDATA *gb_data = GBT_add_data(gb_new_species, ali_names[no_of_alignments], "data", GB_STRING); |
|---|
| 523 | error = GB_write_string(gb_data, seq_data); |
|---|
| 524 | if (!error) id += GBS_checksum(seq_data, 1, ".-"); // creating checksum of the each aligned sequence to generate new accession number |
|---|
| 525 | } |
|---|
| 526 | if (error) error = GB_export_errorf("Can't create alignment '%s'", ali_names[no_of_alignments]); |
|---|
| 527 | } |
|---|
| 528 | } |
|---|
| 529 | |
|---|
| 530 | if (!error) { |
|---|
| 531 | acc = GBS_global_string_copy("ARB_%lX", id); // create new accession number |
|---|
| 532 | error = GBT_write_string(gb_new_species, "acc", acc); |
|---|
| 533 | } |
|---|
| 534 | } |
|---|
| 535 | |
|---|
| 536 | if (!error) error = checkAndMergeFields(gb_new_species, error, scl); |
|---|
| 537 | |
|---|
| 538 | // now generate new name |
|---|
| 539 | if (!error) { |
|---|
| 540 | char *new_species_name = NULp; |
|---|
| 541 | |
|---|
| 542 | const char *add_field = AW_get_nameserver_addid(GLOBAL.gb_main); |
|---|
| 543 | GBDATA *gb_addid = add_field[0] ? GB_entry(gb_new_species, add_field) : NULp; |
|---|
| 544 | char *addid = NULp; |
|---|
| 545 | if (gb_addid) addid = GB_read_as_string(gb_addid); |
|---|
| 546 | |
|---|
| 547 | error = AWTC_generate_one_name(GLOBAL.gb_main, full_name, acc, addid, new_species_name); |
|---|
| 548 | if (!error) { // name was created |
|---|
| 549 | if (GBT_find_species_rel_species_data(gb_species_data, new_species_name)) { |
|---|
| 550 | // if the name is not unique -> create unique name |
|---|
| 551 | UniqueNameDetector und(gb_species_data); |
|---|
| 552 | freeset(new_species_name, AWTC_makeUniqueShortName(new_species_name, und)); |
|---|
| 553 | if (!new_species_name) error = GB_await_error(); |
|---|
| 554 | } |
|---|
| 555 | } |
|---|
| 556 | |
|---|
| 557 | if (!error) error = GBT_write_string(gb_new_species, "name", new_species_name); // insert new 'name' |
|---|
| 558 | |
|---|
| 559 | free(new_species_name); |
|---|
| 560 | free(addid); |
|---|
| 561 | } |
|---|
| 562 | |
|---|
| 563 | error = GB_end_transaction(GLOBAL.gb_main, error); |
|---|
| 564 | if (error) { |
|---|
| 565 | gb_new_species = NULp; |
|---|
| 566 | aw_message(error); |
|---|
| 567 | } |
|---|
| 568 | |
|---|
| 569 | free(acc); |
|---|
| 570 | free(full_name); |
|---|
| 571 | |
|---|
| 572 | return gb_new_species; |
|---|
| 573 | } |
|---|
| 574 | |
|---|
| 575 | enum MergeSpeciesType { |
|---|
| 576 | MERGE_SPECIES_SIMPLE, |
|---|
| 577 | MERGE_SPECIES_AND_CONCAT_ALI, |
|---|
| 578 | }; |
|---|
| 579 | |
|---|
| 580 | static void mergeSimilarSpecies(AW_window *aws, MergeSpeciesType mergeType, AW_selection *selected_alis) { |
|---|
| 581 | nt_assert(correlated(selected_alis, mergeType == MERGE_SPECIES_AND_CONCAT_ALI)); |
|---|
| 582 | |
|---|
| 583 | GB_ERROR error = NULp; |
|---|
| 584 | arb_progress wrapper; |
|---|
| 585 | { |
|---|
| 586 | AW_root *aw_root = aws->get_root(); |
|---|
| 587 | char *merge_field_name = aw_root->awar(AWAR_CON_MERGE_FIELD)->read_string(); |
|---|
| 588 | |
|---|
| 589 | SpeciesConcatenateList *scl = NULp; // to build list of similar species |
|---|
| 590 | SpeciesConcatenateList *newSpeciesList = NULp; // new SpeciesConcatenateList |
|---|
| 591 | |
|---|
| 592 | GB_begin_transaction(GLOBAL.gb_main); // open database for transaction |
|---|
| 593 | |
|---|
| 594 | const char *report_field_name = prepare_and_get_selected_itemfield(aw_root, AWAR_CON_STORE_SIM_SP_NO, GLOBAL.gb_main, SPECIES_get_selector(), FIF_NAME_SELECTED); |
|---|
| 595 | error = GB_incur_error_if(!report_field_name); |
|---|
| 596 | |
|---|
| 597 | if (!error && strcmp(merge_field_name, NO_FIELD_SELECTED) == 0) { |
|---|
| 598 | error = "Please select database field for similarity detection"; |
|---|
| 599 | } |
|---|
| 600 | |
|---|
| 601 | if (!error) { |
|---|
| 602 | PersistentNameServerConnection stayAlive; |
|---|
| 603 | arb_progress progress("Merging similar species", GBT_count_marked_species(GLOBAL.gb_main)); |
|---|
| 604 | progress.auto_subtitles("Species"); |
|---|
| 605 | |
|---|
| 606 | for (GBDATA * gb_species = GBT_first_marked_species(GLOBAL.gb_main); |
|---|
| 607 | gb_species && !error; |
|---|
| 608 | gb_species = GBT_next_marked_species(gb_species)) |
|---|
| 609 | { |
|---|
| 610 | GBDATA *gb_species_field = GB_entry(gb_species, merge_field_name); |
|---|
| 611 | const char *name = GBT_read_name(gb_species); |
|---|
| 612 | |
|---|
| 613 | if (!gb_species_field) { |
|---|
| 614 | // exit if species doesn't have any data in the selected field |
|---|
| 615 | error = GBS_global_string("Species '%s' does not contain data in selected field '%s'", name, merge_field_name); |
|---|
| 616 | } |
|---|
| 617 | else { |
|---|
| 618 | char *gb_species_field_content = GB_read_as_string(gb_species_field); |
|---|
| 619 | int similar_species = 0; |
|---|
| 620 | |
|---|
| 621 | for (GBDATA * gb_species_next = GBT_next_marked_species(gb_species); |
|---|
| 622 | gb_species_next && !error; |
|---|
| 623 | gb_species_next = GBT_next_marked_species(gb_species_next)) |
|---|
| 624 | { |
|---|
| 625 | GBDATA *gb_next_species_field = GB_entry(gb_species_next, merge_field_name); |
|---|
| 626 | const char *next_name = GBT_read_name(gb_species_next); |
|---|
| 627 | |
|---|
| 628 | if (!gb_next_species_field) { |
|---|
| 629 | // exit if species doesn't have any data in the selected field |
|---|
| 630 | error = GBS_global_string("Species '%s' does not contain data in selected field '%s'", next_name, merge_field_name); |
|---|
| 631 | } |
|---|
| 632 | else { |
|---|
| 633 | char *gb_next_species_field_content = GB_read_as_string(gb_next_species_field); |
|---|
| 634 | |
|---|
| 635 | if (strcmp(gb_species_field_content, gb_next_species_field_content) == 0) { |
|---|
| 636 | addSpeciesToConcatenateList(&scl, next_name); |
|---|
| 637 | GB_write_flag(gb_species_next, 0); |
|---|
| 638 | ++similar_species; |
|---|
| 639 | ++progress; |
|---|
| 640 | } |
|---|
| 641 | free(gb_next_species_field_content); |
|---|
| 642 | } |
|---|
| 643 | } |
|---|
| 644 | |
|---|
| 645 | if (similar_species > 0 && !error) { |
|---|
| 646 | ++similar_species; // correct merge counter |
|---|
| 647 | addSpeciesToConcatenateList(&scl, name); |
|---|
| 648 | GB_write_flag(gb_species, 0); |
|---|
| 649 | |
|---|
| 650 | GBDATA *new_species_created = concatenateFieldsCreateNewSpecies(aws, gb_species, scl); |
|---|
| 651 | |
|---|
| 652 | nt_assert(new_species_created); |
|---|
| 653 | if (new_species_created) { // create a list of newly created species |
|---|
| 654 | addSpeciesToConcatenateList(&newSpeciesList, GBT_read_name(new_species_created)); |
|---|
| 655 | } |
|---|
| 656 | |
|---|
| 657 | if (report_field_name) { |
|---|
| 658 | GBDATA *gb_report = GBT_searchOrCreate_itemfield_according_to_changekey(new_species_created, report_field_name, SPECIES_get_selector().change_key_path); |
|---|
| 659 | if (!gb_report) error = GB_await_error(); |
|---|
| 660 | else error = GB_write_lossless_int(gb_report, similar_species); |
|---|
| 661 | } |
|---|
| 662 | } |
|---|
| 663 | |
|---|
| 664 | freeSpeciesConcatenateList(scl); scl = NULp; |
|---|
| 665 | free(gb_species_field_content); |
|---|
| 666 | } |
|---|
| 667 | |
|---|
| 668 | progress.inc_and_check_user_abort(error); |
|---|
| 669 | } |
|---|
| 670 | } |
|---|
| 671 | |
|---|
| 672 | if (!error) { |
|---|
| 673 | GBT_mark_all(GLOBAL.gb_main, 0); // unmark all species in the database |
|---|
| 674 | int newSpeciesCount = 0; |
|---|
| 675 | |
|---|
| 676 | for (; newSpeciesList; newSpeciesList = newSpeciesList->next) { // mark only newly created species |
|---|
| 677 | GB_write_flag(newSpeciesList->species, 1); |
|---|
| 678 | newSpeciesCount++; |
|---|
| 679 | } |
|---|
| 680 | aw_message(GBS_global_string("%i new species were created by taking \"%s\" as a criterion!", newSpeciesCount, merge_field_name)); |
|---|
| 681 | freeSpeciesConcatenateList(newSpeciesList); |
|---|
| 682 | } |
|---|
| 683 | |
|---|
| 684 | free(merge_field_name); |
|---|
| 685 | |
|---|
| 686 | GB_end_transaction_show_error(GLOBAL.gb_main, error, aw_message); |
|---|
| 687 | } |
|---|
| 688 | |
|---|
| 689 | if (mergeType == MERGE_SPECIES_AND_CONCAT_ALI && !error) { |
|---|
| 690 | // @@@ what happens if merge-process above succeeds and concatenateAlignments below fails? |
|---|
| 691 | // @@@ i think both steps should be put into ONE transaction! |
|---|
| 692 | concatenateAlignments(aws, selected_alis); |
|---|
| 693 | } |
|---|
| 694 | } |
|---|
| 695 | |
|---|
| 696 | static AW_window *createMergeSimilarSpeciesWindow(AW_root *aw_root, MergeSpeciesType mergeType, AW_selection *selected_alis) { |
|---|
| 697 | AW_window_simple *aws = new AW_window_simple; |
|---|
| 698 | |
|---|
| 699 | { |
|---|
| 700 | char *window_id = GBS_global_string_copy("MERGE_SPECIES_%i", mergeType); |
|---|
| 701 | const char *window_title = NULp; |
|---|
| 702 | switch (mergeType) { |
|---|
| 703 | case MERGE_SPECIES_SIMPLE: window_title = "Merge species"; break; |
|---|
| 704 | case MERGE_SPECIES_AND_CONCAT_ALI: window_title = "Merge and concatenate"; break; |
|---|
| 705 | } |
|---|
| 706 | aws->init(aw_root, window_id, window_title); |
|---|
| 707 | free(window_id); |
|---|
| 708 | } |
|---|
| 709 | aws->load_xfig("merge_species.fig"); |
|---|
| 710 | |
|---|
| 711 | aws->callback(makeHelpCallback("merge_species.hlp")); |
|---|
| 712 | aws->at("help"); |
|---|
| 713 | aws->create_button("HELP", "HELP", "H"); |
|---|
| 714 | |
|---|
| 715 | create_itemfield_selection_button(aws, FieldSelDef(AWAR_CON_MERGE_FIELD, GLOBAL.gb_main, SPECIES_get_selector(), FIELD_FILTER_STRING_READABLE, "field to compare"), "field_select"); |
|---|
| 716 | create_itemfield_selection_button(aws, FieldSelDef(AWAR_CON_STORE_SIM_SP_NO, GLOBAL.gb_main, SPECIES_get_selector(), FIELD_FILTER_INT_WRITEABLE, "report-field", SF_ALLOW_NEW), "store_sp_no"); |
|---|
| 717 | |
|---|
| 718 | { |
|---|
| 719 | const char *buttonText = NULp; |
|---|
| 720 | switch (mergeType) { |
|---|
| 721 | case MERGE_SPECIES_SIMPLE: buttonText = "Merge similar species"; break; |
|---|
| 722 | case MERGE_SPECIES_AND_CONCAT_ALI: buttonText = "Merge similar species and concat alignments"; break; |
|---|
| 723 | } |
|---|
| 724 | |
|---|
| 725 | aws->at("merge"); |
|---|
| 726 | aws->callback(makeWindowCallback(mergeSimilarSpecies, mergeType, selected_alis)); |
|---|
| 727 | aws->create_autosize_button("MERGE_SIMILAR_SPECIES", buttonText, "M"); |
|---|
| 728 | } |
|---|
| 729 | |
|---|
| 730 | aws->at("close"); |
|---|
| 731 | aws->callback(AW_POPDOWN); |
|---|
| 732 | aws->create_button("CLOSE", "CLOSE", "C"); |
|---|
| 733 | |
|---|
| 734 | return aws; |
|---|
| 735 | } |
|---|
| 736 | |
|---|
| 737 | AW_window *NT_createMergeSimilarSpeciesWindow(AW_root *aw_root) { |
|---|
| 738 | static AW_window *aw = NULp; |
|---|
| 739 | if (!aw) aw = createMergeSimilarSpeciesWindow(aw_root, MERGE_SPECIES_SIMPLE, NULp); |
|---|
| 740 | return aw; |
|---|
| 741 | } |
|---|
| 742 | |
|---|
| 743 | static AW_window *NT_createMergeSimilarSpeciesAndConcatenateWindow(AW_root *aw_root, AW_selection *selected_alis) { |
|---|
| 744 | static AW_window *aw = NULp; |
|---|
| 745 | #if defined(ASSERTION_USED) |
|---|
| 746 | static AW_selection *prev_selected_alis = NULp; |
|---|
| 747 | #endif |
|---|
| 748 | |
|---|
| 749 | if (!aw) { |
|---|
| 750 | aw = createMergeSimilarSpeciesWindow(aw_root, MERGE_SPECIES_AND_CONCAT_ALI, selected_alis); |
|---|
| 751 | #if defined(ASSERTION_USED) |
|---|
| 752 | prev_selected_alis = selected_alis; |
|---|
| 753 | #endif |
|---|
| 754 | } |
|---|
| 755 | #if defined(ASSERTION_USED) |
|---|
| 756 | nt_assert(selected_alis == prev_selected_alis); // would need multiple windows in that case |
|---|
| 757 | #endif |
|---|
| 758 | return aw; |
|---|
| 759 | } |
|---|
| 760 | |
|---|
| 761 | static void useSelectedAlignment(AW_window *aww) { |
|---|
| 762 | AW_root *root = aww->get_root(); |
|---|
| 763 | const char *selali = root->awar(AWAR_CON_SELECTED_ALI)->read_char_pntr(); |
|---|
| 764 | if (selali && strcmp(selali, NO_ALI_SELECTED) != 0) { |
|---|
| 765 | root->awar(AWAR_CON_NEW_ALIGNMENT_NAME)->write_string(selali); |
|---|
| 766 | } |
|---|
| 767 | else { |
|---|
| 768 | aw_message("Select alignment to use in the left alignment list"); |
|---|
| 769 | } |
|---|
| 770 | } |
|---|
| 771 | |
|---|
| 772 | // ----------------------------Creating concatenation window----------------------------------------- |
|---|
| 773 | AW_window *NT_createConcatenationWindow(AW_root *aw_root) { |
|---|
| 774 | AW_window_simple *aws = new AW_window_simple; |
|---|
| 775 | |
|---|
| 776 | aws->init(aw_root, "CONCAT_ALIGNMENTS", "Concatenate Alignments"); |
|---|
| 777 | aws->load_xfig("concatenate.fig"); |
|---|
| 778 | |
|---|
| 779 | aws->auto_space(5, 5); |
|---|
| 780 | aws->button_length(8); |
|---|
| 781 | |
|---|
| 782 | aws->callback(makeHelpCallback("concatenate.hlp")); |
|---|
| 783 | aws->at("help"); |
|---|
| 784 | aws->create_button("HELP", "HELP", "H"); |
|---|
| 785 | |
|---|
| 786 | aws->at("close"); |
|---|
| 787 | aws->callback(AW_POPDOWN); |
|---|
| 788 | aws->create_button("CLOSE", "CLOSE", "C"); |
|---|
| 789 | |
|---|
| 790 | aws->at("dbAligns"); |
|---|
| 791 | AW_DB_selection *all_alis = createSelectionList(GLOBAL.gb_main, aws, AWAR_CON_SELECTED_ALI); |
|---|
| 792 | AW_selection *sel_alis = awt_create_subset_selection_list(aws, all_alis->get_sellist(), "concatAligns", "collect", "sort"); |
|---|
| 793 | |
|---|
| 794 | aws->at("type"); |
|---|
| 795 | aws->create_option_menu(AWAR_CON_SEQUENCE_TYPE, true); |
|---|
| 796 | aws->insert_option("DNA", "d", "dna"); |
|---|
| 797 | aws->insert_option("RNA", "r", "rna"); |
|---|
| 798 | aws->insert_default_option("PROTEIN", "p", "ami"); |
|---|
| 799 | aws->update_option_menu(); |
|---|
| 800 | aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->add_callback(makeRootCallback(alitype_changed_cb, all_alis)); |
|---|
| 801 | |
|---|
| 802 | aws->at("aliSeparator"); |
|---|
| 803 | aws->create_input_field(AWAR_CON_ALIGNMENT_SEPARATOR, 10); |
|---|
| 804 | |
|---|
| 805 | aws->at("aliName"); |
|---|
| 806 | aws->create_input_field(AWAR_CON_NEW_ALIGNMENT_NAME, 25); |
|---|
| 807 | aws->button_length(5); |
|---|
| 808 | aws->callback(useSelectedAlignment); |
|---|
| 809 | aws->create_button("USE", "Use"); |
|---|
| 810 | |
|---|
| 811 | aws->at("overwrite"); |
|---|
| 812 | aws->label("Allow to overwrite an existing alignment?"); |
|---|
| 813 | aws->create_toggle(AWAR_CON_ALLOW_OVERWRITE_ALI); |
|---|
| 814 | |
|---|
| 815 | aws->at("insgaps"); |
|---|
| 816 | aws->label("Insert gaps for missing alignment data?"); |
|---|
| 817 | aws->create_toggle(AWAR_CON_INSGAPS_FOR_MISS_ALIS); |
|---|
| 818 | |
|---|
| 819 | aws->button_length(22); |
|---|
| 820 | aws->at("go"); |
|---|
| 821 | |
|---|
| 822 | aws->callback(makeWindowCallback(concatenateAlignments, sel_alis)); |
|---|
| 823 | aws->create_button("CONCATENATE", "CONCATENATE", "A"); |
|---|
| 824 | |
|---|
| 825 | aws->callback(NT_createMergeSimilarSpeciesWindow); |
|---|
| 826 | aws->create_button("MERGE_SPECIES", "MERGE SIMILAR SPECIES", "M"); |
|---|
| 827 | |
|---|
| 828 | aws->callback(makeCreateWindowCallback(NT_createMergeSimilarSpeciesAndConcatenateWindow, sel_alis)); |
|---|
| 829 | aws->create_button("MERGE_CONCATENATE", "MERGE & CONCATENATE", "S"); |
|---|
| 830 | |
|---|
| 831 | return aws; |
|---|
| 832 | } |
|---|
| 833 | // ------------------------------------------------------------------------------------------------------- |
|---|