| 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 (yadhu@mikro.biologie.tu-muenchen.de) */ |
|---|
| 7 | /* web site : http://www.arb-home.de/ */ |
|---|
| 8 | /* */ |
|---|
| 9 | /* Copyright Department of Microbiology (Technical University Munich) */ |
|---|
| 10 | /* */ |
|---|
| 11 | /*=======================================================================================*/ |
|---|
| 12 | |
|---|
| 13 | #include <stdio.h> |
|---|
| 14 | #include <stdlib.h> |
|---|
| 15 | #include <unistd.h> |
|---|
| 16 | #include <time.h> |
|---|
| 17 | #include <string.h> |
|---|
| 18 | #include <memory.h> |
|---|
| 19 | #include <iostream> |
|---|
| 20 | |
|---|
| 21 | #include <arbdb.h> |
|---|
| 22 | #include <arbdbt.h> |
|---|
| 23 | #include <aw_root.hxx> |
|---|
| 24 | #include <aw_device.hxx> |
|---|
| 25 | #include <aw_window.hxx> |
|---|
| 26 | #include <aw_awars.hxx> |
|---|
| 27 | #include <awt.hxx> |
|---|
| 28 | #include <AW_rename.hxx> |
|---|
| 29 | #include <awt_tree.hxx> |
|---|
| 30 | #include <awt_canvas.hxx> |
|---|
| 31 | #include <awt_item_sel_list.hxx> |
|---|
| 32 | #include <awt_sel_boxes.hxx> |
|---|
| 33 | #include "awtlocal.hxx" |
|---|
| 34 | #include <aw_question.hxx> |
|---|
| 35 | #include "nt_internal.h" |
|---|
| 36 | #include <nt_sort.hxx> // for sorting database entries |
|---|
| 37 | |
|---|
| 38 | #ifndef ARB_ASSERT_H |
|---|
| 39 | #include <arb_assert.h> |
|---|
| 40 | #endif |
|---|
| 41 | #define nt_assert(bed) arb_assert(bed) |
|---|
| 42 | |
|---|
| 43 | using namespace std; |
|---|
| 44 | |
|---|
| 45 | #define AWAR_CON_SEQUENCE_TYPE "tmp/concat/sequence_type" |
|---|
| 46 | #define AWAR_CON_NEW_ALIGNMENT_NAME "tmp/concat/new_alignment_name" |
|---|
| 47 | #define AWAR_CON_ALIGNMENT_SEPARATOR "tmp/concat/alignment_separator" |
|---|
| 48 | #define AWAR_CON_DB_ALIGNS "tmp/concat/database_alignments" |
|---|
| 49 | #define AWAR_CON_CONCAT_ALIGNS "tmp/concat/concatenating_alignments" |
|---|
| 50 | #define AWAR_CON_DUMMY "tmp/concat/dummy" |
|---|
| 51 | #define AWAR_CON_MERGE_FIELD "tmp/concat/merge_field" |
|---|
| 52 | #define AWAR_CON_STORE_SIM_SP_NO "tmp/concat/store_sim_sp_no" |
|---|
| 53 | |
|---|
| 54 | #define MERGE_SIMILAR_CONCATENATE_ALIGNMENTS 1 |
|---|
| 55 | #define MOVE_DOWN 0 |
|---|
| 56 | #define MOVE_UP 1 |
|---|
| 57 | |
|---|
| 58 | struct conAlignStruct{ |
|---|
| 59 | GBDATA *gb_main; |
|---|
| 60 | AW_window *aws; |
|---|
| 61 | AW_root *awr; |
|---|
| 62 | AW_selection_list *db_id; |
|---|
| 63 | AW_selection_list *con_id; |
|---|
| 64 | char *seqType; |
|---|
| 65 | }; |
|---|
| 66 | |
|---|
| 67 | struct SPECIES_ConcatenateList { |
|---|
| 68 | GBDATA *species; |
|---|
| 69 | char *species_name; |
|---|
| 70 | struct SPECIES_ConcatenateList *next; |
|---|
| 71 | }; |
|---|
| 72 | typedef struct SPECIES_ConcatenateList *speciesConcatenateList; |
|---|
| 73 | |
|---|
| 74 | extern GBDATA *GLOBAL_gb_main; |
|---|
| 75 | static AW_selection_list *con_alignment_list; |
|---|
| 76 | static AW_selection_list *db_alignment_list; |
|---|
| 77 | |
|---|
| 78 | /*--------------------------creating and initializing AWARS----------------------------------------*/ |
|---|
| 79 | void NT_createConcatenationAwars(AW_root *aw_root, AW_default aw_def) { |
|---|
| 80 | aw_root->awar_string( AWAR_CON_SEQUENCE_TYPE, "ami" , aw_def); |
|---|
| 81 | aw_root->awar_string( AWAR_CON_NEW_ALIGNMENT_NAME, "ali_concat" , aw_def); |
|---|
| 82 | aw_root->awar_string( AWAR_CON_ALIGNMENT_SEPARATOR,"XXX", aw_def); |
|---|
| 83 | aw_root->awar_string( AWAR_CON_MERGE_FIELD, "full_name" , aw_def); |
|---|
| 84 | aw_root->awar_string( AWAR_CON_STORE_SIM_SP_NO, "merged_species" , aw_def); |
|---|
| 85 | aw_root->awar_string( AWAR_CON_DB_ALIGNS, "" , aw_def); |
|---|
| 86 | aw_root->awar_string( AWAR_CON_CONCAT_ALIGNS, "" , aw_def); |
|---|
| 87 | aw_root->awar_string( AWAR_CON_DUMMY, "" , aw_def); |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | /*------------------------Selecting alignments from the database for concatenation----------------------*/ |
|---|
| 91 | void createSelectionList_callBack(struct conAlignStruct *cas){ |
|---|
| 92 | GBDATA *gb_alignment; |
|---|
| 93 | GBDATA *gb_alignment_name; |
|---|
| 94 | GBDATA *gb_alignment_type; |
|---|
| 95 | char *alignment_name; |
|---|
| 96 | char *alignment_type; |
|---|
| 97 | |
|---|
| 98 | GB_push_transaction(GLOBAL_gb_main); //opening a transaction if not opened yet |
|---|
| 99 | |
|---|
| 100 | AW_root *aw_root = cas->aws->get_root(); |
|---|
| 101 | char *ali_type = aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->read_string(); |
|---|
| 102 | ali_type = GBS_global_string_copy("%s=", ali_type); |
|---|
| 103 | |
|---|
| 104 | cas->aws->clear_selection_list(cas->db_id); //clearing the selection list |
|---|
| 105 | |
|---|
| 106 | for (gb_alignment = GB_search(GLOBAL_gb_main,"presets/alignment",GB_FIND); |
|---|
| 107 | gb_alignment; |
|---|
| 108 | gb_alignment = GB_nextEntry(gb_alignment)) |
|---|
| 109 | { |
|---|
| 110 | gb_alignment_type = GB_entry(gb_alignment,"alignment_type"); |
|---|
| 111 | gb_alignment_name = GB_entry(gb_alignment,"alignment_name"); |
|---|
| 112 | alignment_type = GB_read_string(gb_alignment_type); |
|---|
| 113 | alignment_name = GB_read_string(gb_alignment_name); |
|---|
| 114 | |
|---|
| 115 | char *str = GBS_string_eval(alignment_type, ali_type, 0); //selecting the alignments of the selected sequence type |
|---|
| 116 | if (!*str){ |
|---|
| 117 | cas->aws->insert_selection( cas->db_id, alignment_name, alignment_name ); //inserting to the selection list |
|---|
| 118 | } |
|---|
| 119 | free(str); |
|---|
| 120 | free(alignment_type); |
|---|
| 121 | free(alignment_name); |
|---|
| 122 | } |
|---|
| 123 | cas->aws->insert_default_selection( cas->db_id, "????", "????" ); |
|---|
| 124 | cas->aws->update_selection_list( cas->db_id ); |
|---|
| 125 | |
|---|
| 126 | GB_pop_transaction(GLOBAL_gb_main); //closing a transaction |
|---|
| 127 | free(ali_type); |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | static void createSelectionList_callBack_gb(GBDATA*,int *cl_cas, GB_CB_TYPE cbtype) { |
|---|
| 131 | if (cbtype == GB_CB_CHANGED) { |
|---|
| 132 | struct conAlignStruct *cas = (struct conAlignStruct*)cl_cas; |
|---|
| 133 | createSelectionList_callBack(cas); |
|---|
| 134 | } |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | static void createSelectionList_callBack_awar(AW_root *IF_DEBUG(aw_root), AW_CL cl_cas) { |
|---|
| 138 | struct conAlignStruct *cas = (struct conAlignStruct*)cl_cas; |
|---|
| 139 | gb_assert(aw_root==cas->aws->get_root()); |
|---|
| 140 | createSelectionList_callBack(cas); |
|---|
| 141 | //clear the selected alignments and set default to ???? |
|---|
| 142 | cas->aws->clear_selection_list(con_alignment_list); |
|---|
| 143 | cas->aws->insert_default_selection(con_alignment_list,"????", "????" ); |
|---|
| 144 | cas->aws->update_selection_list(con_alignment_list); |
|---|
| 145 | } |
|---|
| 146 | |
|---|
| 147 | |
|---|
| 148 | conAlignStruct* createSelectionList(GBDATA *gb_main,AW_window *aws, const char *awarName){ |
|---|
| 149 | |
|---|
| 150 | #ifdef DEBUG |
|---|
| 151 | static bool ran=false; |
|---|
| 152 | gb_assert(!ran); |
|---|
| 153 | ran=true; //prevents calling this function for the second time |
|---|
| 154 | #endif |
|---|
| 155 | |
|---|
| 156 | GBDATA *gb_presets; |
|---|
| 157 | AW_root *aw_root = aws->get_root(); |
|---|
| 158 | char *ali_type = aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->read_string(); //reading sequence type from the concatenation window |
|---|
| 159 | ali_type = GBS_global_string_copy("%s=", ali_type); // copying the awar with '=' appended to it |
|---|
| 160 | |
|---|
| 161 | db_alignment_list = aws->create_selection_list(awarName,0,"",10,20); |
|---|
| 162 | |
|---|
| 163 | conAlignStruct *cas = 0; |
|---|
| 164 | cas = new conAlignStruct; // don't free (used in callback) |
|---|
| 165 | cas->aws = aws; |
|---|
| 166 | cas->gb_main = gb_main; |
|---|
| 167 | cas->db_id = db_alignment_list; |
|---|
| 168 | cas->seqType = 0; if (ali_type) cas->seqType = strdup(ali_type); //assigning the sequence type to struct cas |
|---|
| 169 | |
|---|
| 170 | createSelectionList_callBack(cas); // calling callback to get the alignments in the database |
|---|
| 171 | |
|---|
| 172 | GB_push_transaction(gb_main); |
|---|
| 173 | gb_presets = GB_search(gb_main,"presets",GB_CREATE_CONTAINER); |
|---|
| 174 | GB_add_callback(gb_presets, GB_CB_CHANGED, createSelectionList_callBack_gb, (int *)cas); |
|---|
| 175 | GB_pop_transaction(gb_main); |
|---|
| 176 | |
|---|
| 177 | free(ali_type); |
|---|
| 178 | return cas; |
|---|
| 179 | |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | void selectAlignment(AW_window *aws){ |
|---|
| 183 | AW_root *aw_root = aws->get_root(); |
|---|
| 184 | char *selected_alignment = aw_root->awar(AWAR_CON_DB_ALIGNS)->read_string(); |
|---|
| 185 | |
|---|
| 186 | if (selected_alignment && selected_alignment[0] != 0 && selected_alignment[0] != '?') { |
|---|
| 187 | int left_index = aws->get_index_of_element(db_alignment_list, selected_alignment); |
|---|
| 188 | bool entry_found = false; |
|---|
| 189 | |
|---|
| 190 | // browse thru the entries and insert the selection if not in the selected list |
|---|
| 191 | for (const char *listEntry = con_alignment_list->first_element(); |
|---|
| 192 | !entry_found && listEntry; |
|---|
| 193 | listEntry = con_alignment_list->next_element()) |
|---|
| 194 | { |
|---|
| 195 | if (strcmp(listEntry, selected_alignment) == 0) { |
|---|
| 196 | entry_found = true; // entry does already exist in right list |
|---|
| 197 | } |
|---|
| 198 | } |
|---|
| 199 | |
|---|
| 200 | if (!entry_found) { // if not yet in right list |
|---|
| 201 | aws->insert_selection(con_alignment_list, selected_alignment, selected_alignment); |
|---|
| 202 | aws->update_selection_list(con_alignment_list); |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | aws->select_index(db_alignment_list, AWAR_CON_DB_ALIGNS, left_index+1); // go down 1 position on left side |
|---|
| 206 | aw_root->awar(AWAR_CON_CONCAT_ALIGNS)->write_string(selected_alignment); // position right side to newly added or already existing alignment |
|---|
| 207 | } |
|---|
| 208 | free(selected_alignment); |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | |
|---|
| 212 | void selectAllAlignments(AW_window *aws){ |
|---|
| 213 | const char *listEntry = db_alignment_list->first_element(); |
|---|
| 214 | aws->clear_selection_list(con_alignment_list); |
|---|
| 215 | |
|---|
| 216 | while (listEntry) { |
|---|
| 217 | aws->insert_selection(con_alignment_list, listEntry, listEntry); |
|---|
| 218 | listEntry = db_alignment_list->next_element(); |
|---|
| 219 | } |
|---|
| 220 | aws->insert_default_selection(con_alignment_list,"????", "????" ); |
|---|
| 221 | aws->update_selection_list(con_alignment_list); |
|---|
| 222 | } |
|---|
| 223 | |
|---|
| 224 | void clearAlignmentList(AW_window *aws){ |
|---|
| 225 | aws->clear_selection_list(con_alignment_list); |
|---|
| 226 | aws->insert_default_selection(con_alignment_list,"????", "????" ); |
|---|
| 227 | aws->update_selection_list(con_alignment_list); |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | void removeAlignment(AW_window *aws){ |
|---|
| 231 | AW_root *aw_root = aws->get_root(); |
|---|
| 232 | char *selected_alignment = aw_root->awar(AWAR_CON_CONCAT_ALIGNS)->read_string(); |
|---|
| 233 | |
|---|
| 234 | if (selected_alignment && selected_alignment[0] != 0) { |
|---|
| 235 | int index = aws->get_index_of_element(con_alignment_list, selected_alignment); // save old position |
|---|
| 236 | aws->delete_selection_from_list(con_alignment_list, selected_alignment); |
|---|
| 237 | aws->insert_default_selection(con_alignment_list,"????", "????" ); |
|---|
| 238 | aws->update_selection_list(con_alignment_list); |
|---|
| 239 | |
|---|
| 240 | aws->select_index(con_alignment_list, AWAR_CON_CONCAT_ALIGNS, index); // restore old position |
|---|
| 241 | aw_root->awar(AWAR_CON_DB_ALIGNS)->write_string(selected_alignment); // set left selection to deleted alignment |
|---|
| 242 | } |
|---|
| 243 | free(selected_alignment); |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | void shiftAlignment(AW_window *aws, long int direction){ |
|---|
| 247 | AW_root *aw_root = aws->get_root(); |
|---|
| 248 | AW_selection_list *temp_list = aws->create_selection_list(AWAR_CON_DUMMY,0,"",0,0); |
|---|
| 249 | char *selected_alignment = aw_root->awar(AWAR_CON_CONCAT_ALIGNS)->read_string(); |
|---|
| 250 | |
|---|
| 251 | if (!selected_alignment || !selected_alignment[0] || selected_alignment[0] == '?') { |
|---|
| 252 | free(selected_alignment); |
|---|
| 253 | return; |
|---|
| 254 | } |
|---|
| 255 | |
|---|
| 256 | int curr_index = 0; |
|---|
| 257 | int sel_element_index = aws->get_index_of_element(con_alignment_list, selected_alignment); |
|---|
| 258 | const char *listEntry = con_alignment_list->first_element(); |
|---|
| 259 | const char *temp_listEntry = 0; |
|---|
| 260 | |
|---|
| 261 | aws->clear_selection_list(temp_list); |
|---|
| 262 | |
|---|
| 263 | while(listEntry){ |
|---|
| 264 | switch(direction) { |
|---|
| 265 | case MOVE_UP: //shifting alignments upwards |
|---|
| 266 | if (sel_element_index == curr_index+1){ |
|---|
| 267 | aws->insert_selection(temp_list, selected_alignment, selected_alignment); |
|---|
| 268 | temp_listEntry = aws->get_element_of_index(con_alignment_list, curr_index++); |
|---|
| 269 | if (temp_listEntry) aws->insert_selection(temp_list, temp_listEntry, temp_listEntry); |
|---|
| 270 | } |
|---|
| 271 | else { |
|---|
| 272 | temp_listEntry = aws->get_element_of_index(con_alignment_list, curr_index); |
|---|
| 273 | if (temp_listEntry) aws->insert_selection(temp_list, temp_listEntry, temp_listEntry); |
|---|
| 274 | } |
|---|
| 275 | curr_index++; |
|---|
| 276 | break; |
|---|
| 277 | |
|---|
| 278 | case MOVE_DOWN: //shifting alignments downwards |
|---|
| 279 | if (sel_element_index == curr_index){ |
|---|
| 280 | temp_listEntry = aws->get_element_of_index(con_alignment_list, ++curr_index); |
|---|
| 281 | if (temp_listEntry) aws->insert_selection(temp_list, temp_listEntry, temp_listEntry); |
|---|
| 282 | aws->insert_selection(temp_list, selected_alignment, selected_alignment); |
|---|
| 283 | } |
|---|
| 284 | else { |
|---|
| 285 | temp_listEntry = aws->get_element_of_index(con_alignment_list, curr_index); |
|---|
| 286 | if (temp_listEntry) aws->insert_selection(temp_list, temp_listEntry, temp_listEntry); |
|---|
| 287 | } |
|---|
| 288 | curr_index++; |
|---|
| 289 | break; |
|---|
| 290 | } |
|---|
| 291 | listEntry = con_alignment_list->next_element(); |
|---|
| 292 | } |
|---|
| 293 | |
|---|
| 294 | aws->clear_selection_list(con_alignment_list); |
|---|
| 295 | listEntry = temp_list->first_element(); |
|---|
| 296 | |
|---|
| 297 | while (listEntry) { |
|---|
| 298 | aws->insert_selection(con_alignment_list, listEntry, listEntry); |
|---|
| 299 | listEntry = temp_list->next_element(); |
|---|
| 300 | } |
|---|
| 301 | aws->insert_default_selection(con_alignment_list,"????", "????" ); |
|---|
| 302 | aws->update_selection_list(con_alignment_list); |
|---|
| 303 | free(selected_alignment); |
|---|
| 304 | } |
|---|
| 305 | |
|---|
| 306 | /*---------- Create SAI to display alignments that were concatenated --------------*/ |
|---|
| 307 | |
|---|
| 308 | GB_ERROR displayAlignmentInfo(GBDATA *gb_main, GB_ERROR error, char *new_ali_name, char *alignment_separator){ |
|---|
| 309 | GBDATA *gb_extended = GBT_find_or_create_SAI(gb_main,"Alignment Information"); |
|---|
| 310 | GBDATA *gb_data = GBT_add_data(gb_extended, new_ali_name,"data", GB_STRING); |
|---|
| 311 | GBS_strstruct *ali_str = GBS_stropen(GBT_get_alignment_len(gb_main,new_ali_name)); |
|---|
| 312 | const char *const_ali_name = con_alignment_list->first_element(); |
|---|
| 313 | |
|---|
| 314 | while (const_ali_name){ |
|---|
| 315 | int alignment_len = GBT_get_alignment_len(gb_main,const_ali_name); |
|---|
| 316 | int ali_str_len = strlen(const_ali_name); |
|---|
| 317 | for (int pos = 0; pos<alignment_len; pos++) { |
|---|
| 318 | if (pos<5) GBS_strcat(ali_str,"<"); |
|---|
| 319 | else if (pos >= (alignment_len-5)) GBS_strcat(ali_str,">"); |
|---|
| 320 | else if (pos == (alignment_len/2 - ali_str_len/2)) { GBS_strcat(ali_str,const_ali_name); pos+=ali_str_len-1;} |
|---|
| 321 | else GBS_strcat(ali_str,"="); |
|---|
| 322 | } |
|---|
| 323 | const_ali_name = con_alignment_list->next_element(); |
|---|
| 324 | if (const_ali_name) GBS_strcat(ali_str,alignment_separator); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | char *ali_info_SAI = GBS_strclose(ali_str); |
|---|
| 328 | if(!error) error = GB_write_string(gb_data,ali_info_SAI); |
|---|
| 329 | free(ali_info_SAI); |
|---|
| 330 | return error; |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | /*---------------------------------------- Concatenation function ----------------------------------*/ |
|---|
| 334 | void concatenateAlignments(AW_window *aws) { |
|---|
| 335 | |
|---|
| 336 | GB_push_transaction(GLOBAL_gb_main); |
|---|
| 337 | AW_root *aw_root = aws->get_root(); |
|---|
| 338 | |
|---|
| 339 | int no_of_sel_alignments = aws->get_no_of_entries(con_alignment_list); //getting number of selected alignments |
|---|
| 340 | int found[no_of_sel_alignments], missing[no_of_sel_alignments]; |
|---|
| 341 | for (int j = 0; j<no_of_sel_alignments; j++) { found[j] = 0; missing[j] = 0; } //initializing found and missing alis |
|---|
| 342 | |
|---|
| 343 | const char *const_ali_name = con_alignment_list->first_element(); |
|---|
| 344 | long new_alignment_len = 0; |
|---|
| 345 | |
|---|
| 346 | while(const_ali_name){ //computing the length for the new concatenated alignment |
|---|
| 347 | new_alignment_len += GBT_get_alignment_len(GLOBAL_gb_main, const_ali_name); |
|---|
| 348 | const_ali_name = con_alignment_list->next_element(); |
|---|
| 349 | } |
|---|
| 350 | |
|---|
| 351 | char *new_ali_name = aw_root->awar(AWAR_CON_NEW_ALIGNMENT_NAME)->read_string(); |
|---|
| 352 | GB_ERROR error = GBT_check_alignment_name(new_ali_name); |
|---|
| 353 | |
|---|
| 354 | if (!error) { /// handle error |
|---|
| 355 | GBDATA *gb_presets = GB_search(GLOBAL_gb_main, "presets", GB_CREATE_CONTAINER); |
|---|
| 356 | GBDATA *gb_alignment_exists = GB_find_string(gb_presets, "alignment_name", new_ali_name, GB_IGNORE_CASE, down_2_level); |
|---|
| 357 | GBDATA *gb_new_alignment = 0; |
|---|
| 358 | char *seq_type = aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->read_string(); |
|---|
| 359 | |
|---|
| 360 | if (gb_alignment_exists) { // check wheather new alignment exists or not, if yes prompt user to overwrite the existing alignment; if no create an empty alignment |
|---|
| 361 | bool overwrite = aw_ask_sure(GBS_global_string("Existing data in alignment \"%s\" may be overwritten. Do you want to continue?", new_ali_name)); |
|---|
| 362 | if (!overwrite) { |
|---|
| 363 | error = "Alignment exists! Quitting function..."; |
|---|
| 364 | } |
|---|
| 365 | else { |
|---|
| 366 | gb_new_alignment = GBT_get_alignment(GLOBAL_gb_main,new_ali_name); |
|---|
| 367 | if (!gb_new_alignment) error = GB_await_error(); |
|---|
| 368 | } |
|---|
| 369 | } |
|---|
| 370 | else { |
|---|
| 371 | gb_new_alignment = GBT_create_alignment(GLOBAL_gb_main,new_ali_name,new_alignment_len,0,0,seq_type); |
|---|
| 372 | if (!gb_new_alignment) error = GB_await_error(); |
|---|
| 373 | } |
|---|
| 374 | |
|---|
| 375 | if (!error && !con_alignment_list->first_element()) error = "No alignments were selected to concatenate!"; |
|---|
| 376 | else if (!error && !con_alignment_list->next_element()) error ="Select more than 1 alignment to concatenate!"; |
|---|
| 377 | |
|---|
| 378 | if (!error) { |
|---|
| 379 | char *alignment_separator = aw_root->awar(AWAR_CON_ALIGNMENT_SEPARATOR)->read_string(); |
|---|
| 380 | AW_repeated_question ask_about_missing_alignment; |
|---|
| 381 | |
|---|
| 382 | for (GBDATA *gb_species = GBT_first_marked_species(GLOBAL_gb_main); gb_species; gb_species = GBT_next_marked_species(gb_species)){ |
|---|
| 383 | GBS_strstruct *str_seq = GBS_stropen(new_alignment_len+1000); /* create output stream */ |
|---|
| 384 | int ali_len = 0; |
|---|
| 385 | int ali_ctr = 0; |
|---|
| 386 | |
|---|
| 387 | const_ali_name = con_alignment_list->first_element(); |
|---|
| 388 | |
|---|
| 389 | while(const_ali_name){ // concatenation of the selected alignments in the database |
|---|
| 390 | GBDATA *gb_seq_data = GBT_read_sequence(gb_species, const_ali_name); |
|---|
| 391 | if (gb_seq_data) { |
|---|
| 392 | const char *str_data = GB_read_char_pntr(gb_seq_data); |
|---|
| 393 | GBS_strcat(str_seq,str_data); |
|---|
| 394 | ++found[ali_ctr]; |
|---|
| 395 | } |
|---|
| 396 | else { |
|---|
| 397 | char *speciesName = GB_read_string(GB_entry(gb_species, "full_name")); |
|---|
| 398 | char *question = GBS_global_string_copy("\"%s\" alignment doesn't exist in \"%s\"!", const_ali_name, speciesName); |
|---|
| 399 | int skip_ali = ask_about_missing_alignment.get_answer(question, "Insert Gaps for Missing Alignment,Skip Missing Alignment", "all", true); |
|---|
| 400 | if (!skip_ali) { |
|---|
| 401 | ali_len = GBT_get_alignment_len(GLOBAL_gb_main, const_ali_name); |
|---|
| 402 | for ( int j = 0; j<ali_len; j++) { GBS_strcat(str_seq,"."); } |
|---|
| 403 | } |
|---|
| 404 | ++missing[ali_ctr]; |
|---|
| 405 | free(question); |
|---|
| 406 | free(speciesName); |
|---|
| 407 | } |
|---|
| 408 | const_ali_name = con_alignment_list->next_element(); ali_ctr++; |
|---|
| 409 | if (const_ali_name) GBS_strcat(str_seq,alignment_separator); |
|---|
| 410 | } |
|---|
| 411 | |
|---|
| 412 | { |
|---|
| 413 | char *concatenated_ali_seq_data; |
|---|
| 414 | concatenated_ali_seq_data = GBS_strclose(str_seq); |
|---|
| 415 | GBDATA *gb_data = GBT_add_data(gb_species, new_ali_name, "data", GB_STRING); |
|---|
| 416 | GB_write_string(gb_data, concatenated_ali_seq_data); |
|---|
| 417 | free(concatenated_ali_seq_data); |
|---|
| 418 | } |
|---|
| 419 | } |
|---|
| 420 | |
|---|
| 421 | { /*............. print missing alignments...........*/ |
|---|
| 422 | aw_message(GBS_global_string("Concatenation of Alignments was performed for %ld species.",GBT_count_marked_species(GLOBAL_gb_main))); |
|---|
| 423 | const_ali_name = con_alignment_list->first_element(); int i = 0; |
|---|
| 424 | while (const_ali_name) { |
|---|
| 425 | aw_message(GBS_global_string("%s : Found in %d species & Missing in %d species.",const_ali_name,found[i],missing[i])); |
|---|
| 426 | const_ali_name = con_alignment_list->next_element(); |
|---|
| 427 | i++; |
|---|
| 428 | } |
|---|
| 429 | } |
|---|
| 430 | |
|---|
| 431 | error = displayAlignmentInfo(GLOBAL_gb_main,error,new_ali_name,alignment_separator); |
|---|
| 432 | free(alignment_separator); |
|---|
| 433 | } |
|---|
| 434 | free(seq_type); |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | if (!error) { |
|---|
| 438 | char *nfield = GBS_global_string_copy("%s/data",new_ali_name); |
|---|
| 439 | error = GBT_add_new_changekey(GLOBAL_gb_main, nfield, GB_STRING); |
|---|
| 440 | free(nfield); |
|---|
| 441 | } |
|---|
| 442 | GB_end_transaction_show_error(GLOBAL_gb_main, error, aw_message); |
|---|
| 443 | free(new_ali_name); |
|---|
| 444 | } |
|---|
| 445 | |
|---|
| 446 | static void addSpeciesToConcatenateList(speciesConcatenateList *sclp, GB_CSTR species_name) { |
|---|
| 447 | |
|---|
| 448 | GBDATA *gb_species_data = GB_search(GLOBAL_gb_main, "species_data", GB_CREATE_CONTAINER); |
|---|
| 449 | GBDATA *gb_species = GBT_find_species_rel_species_data(gb_species_data, species_name); |
|---|
| 450 | |
|---|
| 451 | if (gb_species) { |
|---|
| 452 | speciesConcatenateList scl = new SPECIES_ConcatenateList; |
|---|
| 453 | scl->species = gb_species; |
|---|
| 454 | scl->species_name = strdup(species_name); |
|---|
| 455 | scl->next = *sclp; |
|---|
| 456 | *sclp = scl; |
|---|
| 457 | } |
|---|
| 458 | } |
|---|
| 459 | |
|---|
| 460 | static void freeSpeciesConcatenateList(speciesConcatenateList scl){ |
|---|
| 461 | while (scl) { |
|---|
| 462 | speciesConcatenateList next = scl->next; |
|---|
| 463 | free(scl->species_name); |
|---|
| 464 | delete scl; |
|---|
| 465 | scl = next; |
|---|
| 466 | } |
|---|
| 467 | } |
|---|
| 468 | |
|---|
| 469 | GB_ERROR checkAndMergeFields( GBDATA *gb_new_species, GB_ERROR error, speciesConcatenateList scl) { |
|---|
| 470 | |
|---|
| 471 | char *doneFields = strdup(";name;"); // all fields which are already merged |
|---|
| 472 | int doneLen = strlen(doneFields); |
|---|
| 473 | speciesConcatenateList sl = scl; |
|---|
| 474 | int sl_length = 0; while (scl) { sl_length++; scl=scl->next; } //counting no. of similar species stored in the list |
|---|
| 475 | int *fieldStat = new int[sl_length]; // 0 = not used yet ; -1 = doesn't have field ; 1..n = field content (same number means same content) |
|---|
| 476 | |
|---|
| 477 | while (sl && !error) { // with all species do.. |
|---|
| 478 | char *newFields = GB_get_subfields(sl->species); |
|---|
| 479 | char *fieldStart = newFields; // points to ; before next field |
|---|
| 480 | |
|---|
| 481 | while (fieldStart[1] && !error) { // with all subfields of the species do.. |
|---|
| 482 | char *fieldEnd = strchr(fieldStart+1, ';'); |
|---|
| 483 | gb_assert(fieldEnd); |
|---|
| 484 | char behind = fieldEnd[1]; fieldEnd[1] = 0; |
|---|
| 485 | |
|---|
| 486 | if (strstr(doneFields, fieldStart)==0) { // field is not merged yet |
|---|
| 487 | char *fieldName = fieldStart+1; |
|---|
| 488 | int fieldLen = int(fieldEnd-fieldName); |
|---|
| 489 | |
|---|
| 490 | gb_assert(fieldEnd[0]==';'); |
|---|
| 491 | fieldEnd[0] = 0; |
|---|
| 492 | |
|---|
| 493 | GBDATA *gb_field = GB_search(sl->species, fieldName, GB_FIND); |
|---|
| 494 | gb_assert(gb_field); // field has to exist, cause it was found before |
|---|
| 495 | int type = gb_field->flags.type; //GB_TYPE(gb_field); |
|---|
| 496 | |
|---|
| 497 | if (type==GB_STRING) { // we only merge string fields |
|---|
| 498 | int i; int doneSpecies = 0; int nextStat = 1; |
|---|
| 499 | |
|---|
| 500 | for (i=0; i<sl_length; i++) { fieldStat[i] = 0;} // clear field status |
|---|
| 501 | |
|---|
| 502 | while (doneSpecies<sl_length) { // since all species in list were handled |
|---|
| 503 | speciesConcatenateList sl2 = sl; i = 0; |
|---|
| 504 | |
|---|
| 505 | while (sl2) { |
|---|
| 506 | if (fieldStat[i]==0) { |
|---|
| 507 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 508 | if (gb_field) { |
|---|
| 509 | char *content = GB_read_as_string(gb_field); |
|---|
| 510 | speciesConcatenateList sl3 = sl2->next; |
|---|
| 511 | fieldStat[i] = nextStat; |
|---|
| 512 | int j = i+1; doneSpecies++; |
|---|
| 513 | |
|---|
| 514 | while (sl3) { |
|---|
| 515 | if (fieldStat[j]==0) { |
|---|
| 516 | gb_field = GB_search(sl3->species, fieldName, GB_FIND); |
|---|
| 517 | if (gb_field) { |
|---|
| 518 | char *content2 = GB_read_as_string(gb_field); |
|---|
| 519 | if (strcmp(content, content2)==0) { // if contents are the same, they get the same status |
|---|
| 520 | fieldStat[j] = nextStat; |
|---|
| 521 | doneSpecies++; |
|---|
| 522 | } |
|---|
| 523 | free(content2); |
|---|
| 524 | } else { |
|---|
| 525 | fieldStat[j] = -1; |
|---|
| 526 | doneSpecies++; |
|---|
| 527 | } |
|---|
| 528 | } |
|---|
| 529 | sl3 = sl3->next; j++; |
|---|
| 530 | } |
|---|
| 531 | free(content); nextStat++; |
|---|
| 532 | } else { |
|---|
| 533 | fieldStat[i] = -1; // field does not exist here |
|---|
| 534 | doneSpecies++; |
|---|
| 535 | } |
|---|
| 536 | } |
|---|
| 537 | sl2 = sl2->next; i++; |
|---|
| 538 | } |
|---|
| 539 | if (!sl2) break; |
|---|
| 540 | } |
|---|
| 541 | gb_assert(nextStat!=1); // this would mean that none of the species contained the field |
|---|
| 542 | { |
|---|
| 543 | char *new_content = 0; |
|---|
| 544 | int new_content_len = 0; |
|---|
| 545 | |
|---|
| 546 | if (nextStat==2) { // all species contain same field content or do not have the field |
|---|
| 547 | speciesConcatenateList sl2 = sl; |
|---|
| 548 | while (sl2) { |
|---|
| 549 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 550 | if (gb_field) { |
|---|
| 551 | new_content = GB_read_as_string(gb_field); |
|---|
| 552 | new_content_len = strlen(new_content); |
|---|
| 553 | break; |
|---|
| 554 | } |
|---|
| 555 | sl2 = sl2->next; |
|---|
| 556 | } |
|---|
| 557 | } |
|---|
| 558 | else { // different field contents |
|---|
| 559 | int actualStat; |
|---|
| 560 | for (actualStat=1; actualStat<nextStat; actualStat++) { |
|---|
| 561 | int names_len = 1; // open bracket |
|---|
| 562 | speciesConcatenateList sl2 = sl; |
|---|
| 563 | char *content = 0; i = 0; |
|---|
| 564 | |
|---|
| 565 | while (sl2) { |
|---|
| 566 | if (fieldStat[i]==actualStat) { |
|---|
| 567 | names_len += strlen(sl2->species_name)+1; |
|---|
| 568 | if (!content) { |
|---|
| 569 | gb_field = GB_search(sl2->species, fieldName, GB_FIND); |
|---|
| 570 | gb_assert(gb_field); |
|---|
| 571 | content = GB_read_as_string(gb_field); |
|---|
| 572 | } |
|---|
| 573 | } |
|---|
| 574 | sl2 = sl2->next; i++; |
|---|
| 575 | } |
|---|
| 576 | gb_assert(content); |
|---|
| 577 | int add_len = names_len+1+strlen(content); |
|---|
| 578 | char *whole = (char*)malloc(new_content_len+1+add_len+1); |
|---|
| 579 | gb_assert(whole); |
|---|
| 580 | char *add = new_content ? whole+sprintf(whole, "%s ", new_content) : whole; |
|---|
| 581 | sl2 = sl; i = 0; |
|---|
| 582 | int first = 1; |
|---|
| 583 | while (sl2) { |
|---|
| 584 | if (fieldStat[i]==actualStat) { |
|---|
| 585 | add += sprintf(add, "%c%s", first ? '{' : ';', sl2->species_name); |
|---|
| 586 | first = 0; |
|---|
| 587 | } |
|---|
| 588 | sl2 = sl2->next; i++; |
|---|
| 589 | } |
|---|
| 590 | add += sprintf(add, "} %s", content); |
|---|
| 591 | |
|---|
| 592 | free(content); |
|---|
| 593 | freeset(new_content, whole); |
|---|
| 594 | new_content_len = strlen(new_content); |
|---|
| 595 | } |
|---|
| 596 | } |
|---|
| 597 | |
|---|
| 598 | if (new_content) { |
|---|
| 599 | error = GBT_write_string(gb_new_species, fieldName, new_content); |
|---|
| 600 | free(new_content); |
|---|
| 601 | } |
|---|
| 602 | } |
|---|
| 603 | } |
|---|
| 604 | |
|---|
| 605 | // mark field as done: |
|---|
| 606 | char *new_doneFields = (char*)malloc(doneLen+fieldLen+1+1); |
|---|
| 607 | sprintf(new_doneFields, "%s%s;", doneFields, fieldName); |
|---|
| 608 | doneLen += fieldLen+1; |
|---|
| 609 | freeset(doneFields, new_doneFields); |
|---|
| 610 | fieldEnd[0] = ';'; |
|---|
| 611 | } |
|---|
| 612 | fieldEnd[1] = behind; |
|---|
| 613 | fieldStart = fieldEnd; |
|---|
| 614 | } |
|---|
| 615 | free(newFields); |
|---|
| 616 | sl = sl->next; |
|---|
| 617 | } |
|---|
| 618 | free(doneFields); |
|---|
| 619 | delete [] fieldStat; |
|---|
| 620 | |
|---|
| 621 | return error; |
|---|
| 622 | } |
|---|
| 623 | |
|---|
| 624 | GBDATA *concatenateFieldsCreateNewSpecies(AW_window *, GBDATA *gb_species, speciesConcatenateList scl){ |
|---|
| 625 | GB_push_transaction(GLOBAL_gb_main); |
|---|
| 626 | |
|---|
| 627 | GB_ERROR error = 0; |
|---|
| 628 | GBDATA *gb_species_data = GB_search(GLOBAL_gb_main, "species_data", GB_CREATE_CONTAINER); |
|---|
| 629 | |
|---|
| 630 | // data needed for name generation |
|---|
| 631 | char *full_name = 0; |
|---|
| 632 | char *acc = 0; |
|---|
| 633 | char *addid = 0; |
|---|
| 634 | |
|---|
| 635 | /*--------------------getting the species related data --------------------*/ |
|---|
| 636 | |
|---|
| 637 | GBDATA *gb_new_species = 0; |
|---|
| 638 | |
|---|
| 639 | if (!error) { |
|---|
| 640 | // copy species to create a new species |
|---|
| 641 | gb_new_species = GB_create_container(gb_species_data, "species"); |
|---|
| 642 | error = gb_new_species ? GB_copy(gb_new_species, gb_species) : GB_await_error(); |
|---|
| 643 | |
|---|
| 644 | if (!error) { // write dummy-name (real name written below) |
|---|
| 645 | error = GBT_write_string(gb_new_species, "name", "$currcat$"); |
|---|
| 646 | } |
|---|
| 647 | } |
|---|
| 648 | |
|---|
| 649 | if (!error) { // copy full name |
|---|
| 650 | full_name = GBT_read_string(gb_species, "full_name"); |
|---|
| 651 | if (!full_name) error = GB_await_error(); |
|---|
| 652 | else error = GBT_write_string(gb_new_species, "full_name", full_name); |
|---|
| 653 | } |
|---|
| 654 | |
|---|
| 655 | if (!error) { |
|---|
| 656 | char **ali_names = GBT_get_alignment_names(GLOBAL_gb_main); |
|---|
| 657 | long id = 0; |
|---|
| 658 | |
|---|
| 659 | for (speciesConcatenateList speciesList = scl; speciesList; speciesList = speciesList->next) { |
|---|
| 660 | for (int no_of_alignments = 0; ali_names[no_of_alignments]!=0; no_of_alignments++) { |
|---|
| 661 | GBDATA *gb_seq_data = GBT_read_sequence(speciesList->species, ali_names[no_of_alignments]); |
|---|
| 662 | if (gb_seq_data) { |
|---|
| 663 | const char *seq_data = GB_read_char_pntr(gb_seq_data); |
|---|
| 664 | GBDATA *gb_data = GBT_add_data(gb_new_species, ali_names[no_of_alignments], "data", GB_STRING); |
|---|
| 665 | error = GB_write_string(gb_data, seq_data); |
|---|
| 666 | if (!error) id += GBS_checksum(seq_data,1,".-"); //creating checksum of the each aligned sequence to generate new accession number |
|---|
| 667 | } |
|---|
| 668 | if (error) error = GB_export_errorf("Can't create alignment '%s'", ali_names[no_of_alignments]); |
|---|
| 669 | } |
|---|
| 670 | } |
|---|
| 671 | |
|---|
| 672 | if (!error) { |
|---|
| 673 | acc = GBS_global_string_copy("ARB_%lX", id); // create new accession number |
|---|
| 674 | error = GBT_write_string(gb_new_species, "acc", acc); |
|---|
| 675 | } |
|---|
| 676 | |
|---|
| 677 | GBT_free_names(ali_names); |
|---|
| 678 | } |
|---|
| 679 | |
|---|
| 680 | if (!error) error = checkAndMergeFields(gb_new_species, error, scl); |
|---|
| 681 | |
|---|
| 682 | // now generate new name |
|---|
| 683 | if (!error) { |
|---|
| 684 | char *new_species_name = 0; |
|---|
| 685 | |
|---|
| 686 | const char *add_field = AW_get_nameserver_addid(GLOBAL_gb_main); |
|---|
| 687 | GBDATA *gb_addid = add_field[0] ? GB_entry(gb_new_species, add_field) : 0; |
|---|
| 688 | if (gb_addid) addid = GB_read_string(gb_addid); |
|---|
| 689 | |
|---|
| 690 | error = AWTC_generate_one_name(GLOBAL_gb_main, full_name, acc, addid, new_species_name, false, true); |
|---|
| 691 | if (!error) { // name was created |
|---|
| 692 | if (GBT_find_species_rel_species_data(gb_species_data, new_species_name) != 0) { |
|---|
| 693 | // if the name is not unique -> create unique name |
|---|
| 694 | UniqueNameDetector und(gb_species_data); |
|---|
| 695 | freeset(new_species_name, AWTC_makeUniqueShortName(new_species_name, und)); |
|---|
| 696 | if (!new_species_name) error = GB_await_error(); |
|---|
| 697 | } |
|---|
| 698 | } |
|---|
| 699 | |
|---|
| 700 | if (!error) error = GBT_write_string(gb_new_species, "name", new_species_name); // insert new 'name' |
|---|
| 701 | |
|---|
| 702 | free(new_species_name); |
|---|
| 703 | } |
|---|
| 704 | |
|---|
| 705 | error = GB_end_transaction(GLOBAL_gb_main, error); |
|---|
| 706 | if (error) { |
|---|
| 707 | gb_new_species = 0; |
|---|
| 708 | aw_popup_ok(error); |
|---|
| 709 | } |
|---|
| 710 | |
|---|
| 711 | free(addid); |
|---|
| 712 | free(acc); |
|---|
| 713 | free(full_name); |
|---|
| 714 | |
|---|
| 715 | return gb_new_species; |
|---|
| 716 | } |
|---|
| 717 | |
|---|
| 718 | GB_ERROR checkAndCreateNewField(GBDATA *gb_main, char *new_field_name){ |
|---|
| 719 | GB_ERROR error = GB_check_key(new_field_name); |
|---|
| 720 | |
|---|
| 721 | if (error) return error; |
|---|
| 722 | else { |
|---|
| 723 | error = GBT_add_new_changekey(gb_main,new_field_name,GB_STRING); |
|---|
| 724 | if (error) { |
|---|
| 725 | bool overwrite = aw_ask_sure(GBS_global_string("\"%s\" field exists! Do you want to overwrite the existing field?",new_field_name)); |
|---|
| 726 | if (!overwrite) return error; |
|---|
| 727 | } |
|---|
| 728 | } |
|---|
| 729 | return 0; |
|---|
| 730 | } |
|---|
| 731 | |
|---|
| 732 | static void mergeSimilarSpecies(AW_window *aws, AW_CL cl_mergeSimilarConcatenateAlignments) { |
|---|
| 733 | AW_root *aw_root = aws->get_root(); |
|---|
| 734 | char *merge_field_name = aw_root->awar(AWAR_CON_MERGE_FIELD)->read_string(); |
|---|
| 735 | char *new_field_name = aw_root->awar(AWAR_CON_STORE_SIM_SP_NO)->read_string(); |
|---|
| 736 | |
|---|
| 737 | speciesConcatenateList scl = 0; // to build list of similar species |
|---|
| 738 | speciesConcatenateList newSpeciesList = 0; // new SPECIES_ConcatenateList; |
|---|
| 739 | |
|---|
| 740 | GB_begin_transaction(GLOBAL_gb_main); //open database for transaction |
|---|
| 741 | |
|---|
| 742 | GB_ERROR error = checkAndCreateNewField(GLOBAL_gb_main, new_field_name); |
|---|
| 743 | |
|---|
| 744 | for (GBDATA * gb_species = GBT_first_marked_species(GLOBAL_gb_main); |
|---|
| 745 | gb_species && !error; |
|---|
| 746 | gb_species = GBT_next_marked_species(gb_species)) |
|---|
| 747 | { |
|---|
| 748 | GBDATA *gb_species_field = GB_entry(gb_species, merge_field_name); |
|---|
| 749 | const char *name = GBT_read_name(gb_species); |
|---|
| 750 | |
|---|
| 751 | if (!gb_species_field) { |
|---|
| 752 | // exit if species doesn't have any data in the selected field |
|---|
| 753 | error = GBS_global_string("Species '%s' does not contain data in selected field '%s'", name, merge_field_name); |
|---|
| 754 | } |
|---|
| 755 | else { |
|---|
| 756 | char *gb_species_field_content = GB_read_string(gb_species_field); |
|---|
| 757 | int similar_species = 0; |
|---|
| 758 | |
|---|
| 759 | for (GBDATA * gb_species_next = GBT_next_marked_species(gb_species); |
|---|
| 760 | gb_species_next && !error; |
|---|
| 761 | gb_species_next = GBT_next_marked_species(gb_species_next)) |
|---|
| 762 | { |
|---|
| 763 | GBDATA *gb_next_species_field = GB_entry(gb_species_next, merge_field_name); |
|---|
| 764 | const char *next_name = GBT_read_name(gb_species_next); |
|---|
| 765 | |
|---|
| 766 | if (!gb_next_species_field) { |
|---|
| 767 | // exit if species doesn't have any data in the selected field |
|---|
| 768 | error = GBS_global_string("Species '%s' does not contain data in selected field '%s'", next_name, merge_field_name); |
|---|
| 769 | } |
|---|
| 770 | else { |
|---|
| 771 | char *gb_next_species_field_content = GB_read_string(gb_next_species_field); |
|---|
| 772 | |
|---|
| 773 | if (strcmp(gb_species_field_content, gb_next_species_field_content) == 0) { |
|---|
| 774 | addSpeciesToConcatenateList(&scl, next_name); |
|---|
| 775 | GB_write_flag(gb_species_next, 0); |
|---|
| 776 | ++similar_species; |
|---|
| 777 | } |
|---|
| 778 | free(gb_next_species_field_content); |
|---|
| 779 | } |
|---|
| 780 | } |
|---|
| 781 | |
|---|
| 782 | if (similar_species > 0 && !error) { |
|---|
| 783 | addSpeciesToConcatenateList(&scl, name); |
|---|
| 784 | GB_write_flag(gb_species, 0); |
|---|
| 785 | |
|---|
| 786 | GBDATA *new_species_created = concatenateFieldsCreateNewSpecies(aws, gb_species, scl); |
|---|
| 787 | |
|---|
| 788 | gb_assert(new_species_created); |
|---|
| 789 | if (new_species_created) { // create a list of newly created species |
|---|
| 790 | addSpeciesToConcatenateList(&newSpeciesList, GBT_read_name(new_species_created)); |
|---|
| 791 | } |
|---|
| 792 | |
|---|
| 793 | error = GBT_write_int(new_species_created, new_field_name, ++similar_species); |
|---|
| 794 | } |
|---|
| 795 | |
|---|
| 796 | freeSpeciesConcatenateList(scl); scl = 0; |
|---|
| 797 | free(gb_species_field_content); |
|---|
| 798 | } |
|---|
| 799 | } |
|---|
| 800 | |
|---|
| 801 | if (!error) { |
|---|
| 802 | GBT_mark_all(GLOBAL_gb_main, 0); //unmark all species in the database |
|---|
| 803 | int newSpeciesCount = 0; |
|---|
| 804 | |
|---|
| 805 | for (; newSpeciesList; newSpeciesList = newSpeciesList->next) { //mark only newly created species |
|---|
| 806 | GB_write_flag(newSpeciesList->species, 1); |
|---|
| 807 | newSpeciesCount++; |
|---|
| 808 | } |
|---|
| 809 | aw_message(GBS_global_string("%i new species were created by taking \"%s\" as a criterion!", newSpeciesCount, merge_field_name)); |
|---|
| 810 | freeSpeciesConcatenateList(newSpeciesList); |
|---|
| 811 | } |
|---|
| 812 | |
|---|
| 813 | free(merge_field_name); |
|---|
| 814 | free(new_field_name); |
|---|
| 815 | |
|---|
| 816 | GB_end_transaction_show_error(GLOBAL_gb_main, error, aw_message); |
|---|
| 817 | |
|---|
| 818 | // Concatenate alignments of the merged species if cl_mergeSimilarConcatenateAlignments = MERGE_SIMILAR_CONCATENATE_ALIGNMENTS |
|---|
| 819 | if (int (cl_mergeSimilarConcatenateAlignments) && !error) concatenateAlignments(aws); |
|---|
| 820 | } |
|---|
| 821 | |
|---|
| 822 | |
|---|
| 823 | /*----------------------------Creating concatenation window-----------------------------------------*/ |
|---|
| 824 | AW_window *NT_createConcatenationWindow(AW_root *aw_root) { |
|---|
| 825 | AW_window_simple *aws = new AW_window_simple; |
|---|
| 826 | |
|---|
| 827 | aws->init( aw_root, "CONCATENATE_ALIGNMENTS", "CONCATENATION WINDOW"); |
|---|
| 828 | aws->load_xfig("concatenate.fig"); |
|---|
| 829 | |
|---|
| 830 | aws->button_length(8); |
|---|
| 831 | |
|---|
| 832 | aws->callback( AW_POPUP_HELP,(AW_CL)"concatenate.hlp"); |
|---|
| 833 | aws->at("help"); |
|---|
| 834 | aws->create_button("HELP","HELP","H"); |
|---|
| 835 | |
|---|
| 836 | aws->at("close"); |
|---|
| 837 | aws->callback((AW_CB0)AW_POPDOWN); |
|---|
| 838 | aws->create_button("CLOSE","CLOSE","C"); |
|---|
| 839 | |
|---|
| 840 | aws->at("dbAligns"); |
|---|
| 841 | conAlignStruct *cas = createSelectionList(GLOBAL_gb_main, (AW_window *)aws, AWAR_CON_DB_ALIGNS); |
|---|
| 842 | |
|---|
| 843 | aws->at("concatAligns"); |
|---|
| 844 | con_alignment_list = aws->create_selection_list(AWAR_CON_CONCAT_ALIGNS, "concatAligns","N"); |
|---|
| 845 | aws->insert_default_selection(con_alignment_list, "????","????"); |
|---|
| 846 | aws->update_selection_list(con_alignment_list); |
|---|
| 847 | |
|---|
| 848 | aws->at("type"); |
|---|
| 849 | aws->create_option_menu(AWAR_CON_SEQUENCE_TYPE); |
|---|
| 850 | aws->insert_option("DNA","d","dna"); |
|---|
| 851 | aws->insert_option("RNA","r","rna"); |
|---|
| 852 | aws->insert_default_option("PROTEIN","p","ami"); |
|---|
| 853 | aws->update_option_menu(); |
|---|
| 854 | aw_root->awar(AWAR_CON_SEQUENCE_TYPE)->add_callback(createSelectionList_callBack_awar, (AW_CL)cas); //associating selection list callback to sequence type awar |
|---|
| 855 | |
|---|
| 856 | aws->at("add"); |
|---|
| 857 | aws->button_length(6); |
|---|
| 858 | aws->callback(selectAlignment); |
|---|
| 859 | aws->create_button("ADD","#moveRight.bitmap"); |
|---|
| 860 | |
|---|
| 861 | aws->at("addAll"); |
|---|
| 862 | aws->button_length(6); |
|---|
| 863 | aws->callback(selectAllAlignments); |
|---|
| 864 | aws->create_button("ADDALL","#moveAll.bitmap"); |
|---|
| 865 | |
|---|
| 866 | aws->at("remove"); |
|---|
| 867 | aws->button_length(6); |
|---|
| 868 | aws->callback(removeAlignment); |
|---|
| 869 | aws->create_button("REMOVE","#moveLeft.bitmap"); |
|---|
| 870 | |
|---|
| 871 | aws->at("up"); |
|---|
| 872 | aws->button_length(0); |
|---|
| 873 | aws->callback(shiftAlignment, 1); //passing 1 as argument to shift the alignment upwards |
|---|
| 874 | aws->create_button("up","#moveUp.bitmap",0); |
|---|
| 875 | |
|---|
| 876 | aws->at("down"); |
|---|
| 877 | aws->button_length(0); |
|---|
| 878 | aws->callback(shiftAlignment, 0); //passing 0 as argument to shift the alignment downwards |
|---|
| 879 | aws->create_button("down","#moveDown.bitmap",0); |
|---|
| 880 | |
|---|
| 881 | aws->at("clearList"); |
|---|
| 882 | aws->callback(clearAlignmentList); |
|---|
| 883 | aws->create_button("CLEAR","CLEAR LIST","R"); |
|---|
| 884 | |
|---|
| 885 | aws->at("aliName"); |
|---|
| 886 | aws->label_length(15); |
|---|
| 887 | aws->create_input_field(AWAR_CON_NEW_ALIGNMENT_NAME,20); |
|---|
| 888 | |
|---|
| 889 | aws->at("aliSeparator"); |
|---|
| 890 | aws->label_length(5); |
|---|
| 891 | aws->create_input_field(AWAR_CON_ALIGNMENT_SEPARATOR,5); |
|---|
| 892 | |
|---|
| 893 | aws->at("concatenate"); |
|---|
| 894 | aws->callback((AW_CB0)concatenateAlignments); |
|---|
| 895 | aws->create_button("CONCATENATE","CONCATENATE","A"); |
|---|
| 896 | |
|---|
| 897 | aws->at("merge_species"); |
|---|
| 898 | aws->callback(AW_POPUP, (AW_CL)NT_createMergeSimilarSpeciesWindow, 0); |
|---|
| 899 | aws->create_button("MERGE_SPECIES","MERGE SIMILAR SPECIES","M"); |
|---|
| 900 | |
|---|
| 901 | aws->at("merge_concatenate"); |
|---|
| 902 | aws->callback(AW_POPUP, (AW_CL)NT_createMergeSimilarSpeciesAndConcatenateWindow, 0); |
|---|
| 903 | aws->create_button("MERGE_CONCATENATE","MERGE and CONCATENATE","S"); |
|---|
| 904 | |
|---|
| 905 | aws->show(); |
|---|
| 906 | return (AW_window *)aws; |
|---|
| 907 | } |
|---|
| 908 | |
|---|
| 909 | static AW_window *createMergeSimilarSpeciesWindow(AW_root *aw_root, int option) { |
|---|
| 910 | AW_window_simple *aws = new AW_window_simple; |
|---|
| 911 | |
|---|
| 912 | { |
|---|
| 913 | char *window_id = GBS_global_string_copy("MERGE_SPECIES_%i", option); |
|---|
| 914 | aws->init(aw_root, window_id, "MERGE SPECIES WINDOW" ); |
|---|
| 915 | free(window_id); |
|---|
| 916 | } |
|---|
| 917 | aws->load_xfig("merge_species.fig"); |
|---|
| 918 | |
|---|
| 919 | aws->callback( AW_POPUP_HELP,(AW_CL)"merge_species.hlp"); |
|---|
| 920 | aws->at("help"); |
|---|
| 921 | aws->create_button("HELP","HELP","H"); |
|---|
| 922 | |
|---|
| 923 | aws->at("field_select"); |
|---|
| 924 | aws->auto_space(0,0); |
|---|
| 925 | aws->callback(AW_POPDOWN); |
|---|
| 926 | awt_create_selection_list_on_scandb(GLOBAL_gb_main, aws, |
|---|
| 927 | AWAR_CON_MERGE_FIELD, |
|---|
| 928 | AWT_NDS_FILTER, |
|---|
| 929 | "field_select", |
|---|
| 930 | 0, |
|---|
| 931 | &AWT_species_selector, |
|---|
| 932 | 20, 30, |
|---|
| 933 | awt_selected_fields(AWT_SF_PSEUDO|AWT_SF_HIDDEN), |
|---|
| 934 | "sel_merge_field"); |
|---|
| 935 | |
|---|
| 936 | aws->at("store_sp_no"); |
|---|
| 937 | aws->label_length(20); |
|---|
| 938 | aws->create_input_field(AWAR_CON_STORE_SIM_SP_NO,20); |
|---|
| 939 | |
|---|
| 940 | aws->at("merge"); |
|---|
| 941 | aws->callback(mergeSimilarSpecies, option); |
|---|
| 942 | aws->create_button("MERGE_SIMILAR_SPECIES","MERGE SIMILAR SPECIES","M"); |
|---|
| 943 | |
|---|
| 944 | aws->at("close"); |
|---|
| 945 | aws->callback(AW_POPDOWN); |
|---|
| 946 | aws->create_button("CLOSE","CLOSE","C"); |
|---|
| 947 | |
|---|
| 948 | return (AW_window *)aws; |
|---|
| 949 | } |
|---|
| 950 | |
|---|
| 951 | AW_window *NT_createMergeSimilarSpeciesWindow(AW_root *aw_root) { |
|---|
| 952 | static AW_window *aw = 0; |
|---|
| 953 | |
|---|
| 954 | if (!aw) aw = createMergeSimilarSpeciesWindow(aw_root, 0); |
|---|
| 955 | return aw; |
|---|
| 956 | } |
|---|
| 957 | |
|---|
| 958 | AW_window *NT_createMergeSimilarSpeciesAndConcatenateWindow(AW_root *aw_root) { |
|---|
| 959 | static AW_window *aw = 0; |
|---|
| 960 | |
|---|
| 961 | if (!aw) aw = createMergeSimilarSpeciesWindow(aw_root, MERGE_SIMILAR_CONCATENATE_ALIGNMENTS); |
|---|
| 962 | return aw; |
|---|
| 963 | } |
|---|
| 964 | |
|---|
| 965 | /*-------------------------------------------------------------------------------------------------------*/ |
|---|