| 1 | #include "GDE_extglob.h" |
|---|
| 2 | #include "GDE_awars.h" |
|---|
| 3 | |
|---|
| 4 | #include <awt_filter.hxx> |
|---|
| 5 | #include <aw_window.hxx> |
|---|
| 6 | #include <aw_root.hxx> |
|---|
| 7 | #include <aw_question.hxx> |
|---|
| 8 | #include <aw_awar.hxx> |
|---|
| 9 | #include <aw_msg.hxx> |
|---|
| 10 | #include <aw_file.hxx> |
|---|
| 11 | #include <arb_progress.h> |
|---|
| 12 | #include <AP_filter.hxx> |
|---|
| 13 | |
|---|
| 14 | #include <set> |
|---|
| 15 | #include <string> |
|---|
| 16 | |
|---|
| 17 | using namespace std; |
|---|
| 18 | |
|---|
| 19 | #define DEFAULT_COLOR 8 |
|---|
| 20 | extern adfiltercbstruct *agde_filtercd; |
|---|
| 21 | |
|---|
| 22 | /* |
|---|
| 23 | ReplaceArgs(): |
|---|
| 24 | Replace all command line arguments with the appropriate values |
|---|
| 25 | stored for the chosen menu item. |
|---|
| 26 | |
|---|
| 27 | Copyright (c) 1989-1990, University of Illinois board of trustees. All |
|---|
| 28 | rights reserved. Written by Steven Smith at the Center for Prokaryote Genome |
|---|
| 29 | Analysis. Design and implementation guidance by Dr. Gary Olsen and Dr. |
|---|
| 30 | Carl Woese. |
|---|
| 31 | |
|---|
| 32 | Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory. |
|---|
| 33 | All rights reserved. |
|---|
| 34 | |
|---|
| 35 | */ |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | static char *ReplaceArgs(AW_root *awr, char *Action, GmenuItem *gmenuitem, int number) |
|---|
| 39 | { |
|---|
| 40 | /* |
|---|
| 41 | * The basic idea is to replace all of the symbols in the method |
|---|
| 42 | * string with the values picked in the dialog box. The method |
|---|
| 43 | * is the general command line structure. All arguments have three |
|---|
| 44 | * parts, a label, a method, and a value. The method never changes, and |
|---|
| 45 | * is used to represent '-flag's for a given function. Values are the |
|---|
| 46 | * associated arguments that some flags require. All symbols that |
|---|
| 47 | * require argvalue replacement should have a '$' infront of the symbol |
|---|
| 48 | * name in the itemmethod definition. All symbols without the '$' will |
|---|
| 49 | * be replaced by their argmethod. There is currently no way to do a label |
|---|
| 50 | * replacement, as the label is considered to be for use in the dialog |
|---|
| 51 | * box only. An example command line replacement would be: |
|---|
| 52 | * |
|---|
| 53 | * itemmethod=> "lpr arg1 $arg1 $arg2" |
|---|
| 54 | * |
|---|
| 55 | * arglabel arg1=> "To printer?" |
|---|
| 56 | * argmethod arg1=> "-P" |
|---|
| 57 | * argvalue arg1=> "lw" |
|---|
| 58 | * |
|---|
| 59 | * arglabel arg2=> "File name?" |
|---|
| 60 | * argvalue arg2=> "foobar" |
|---|
| 61 | * argmethod arg2=> "" |
|---|
| 62 | * |
|---|
| 63 | * final command line: |
|---|
| 64 | * |
|---|
| 65 | * lpr -P lw foobar |
|---|
| 66 | * |
|---|
| 67 | * At this point, the chooser dialog type only supports the arglabel and |
|---|
| 68 | * argmethod field. So if an argument is of type chooser, and |
|---|
| 69 | * its symbol is "this", then "$this" has no real meaning in the |
|---|
| 70 | * itemmethod definition. Its format in the .GDEmenu file is slighty |
|---|
| 71 | * different as well. A choice from a chooser field looks like: |
|---|
| 72 | * |
|---|
| 73 | * argchoice:Argument_label:Argument_method |
|---|
| 74 | * |
|---|
| 75 | * |
|---|
| 76 | */ |
|---|
| 77 | const char *symbol=0; |
|---|
| 78 | char *method=0; |
|---|
| 79 | char *textvalue=0; |
|---|
| 80 | char *temp; |
|---|
| 81 | int i, newlen, type; |
|---|
| 82 | symbol = gmenuitem->arg[number].symbol; |
|---|
| 83 | type = gmenuitem->arg[number].type; |
|---|
| 84 | if ((type == SLIDER)) { |
|---|
| 85 | char *awarname = GDE_makeawarname(gmenuitem, number); |
|---|
| 86 | textvalue = awr->awar(awarname)->read_as_string(); |
|---|
| 87 | free(awarname); |
|---|
| 88 | } |
|---|
| 89 | else if (type == FILE_SELECTOR) { |
|---|
| 90 | char *awar_base = GDE_maketmpawarname(gmenuitem, number); |
|---|
| 91 | textvalue = AW_get_selected_fullname(awr, awar_base); |
|---|
| 92 | free(awar_base); |
|---|
| 93 | } |
|---|
| 94 | else if ((type == CHOOSER) || |
|---|
| 95 | (type == CHOICE_TREE) || |
|---|
| 96 | (type == CHOICE_SAI) || |
|---|
| 97 | (type == CHOICE_MENU) || |
|---|
| 98 | (type == CHOICE_LIST) || |
|---|
| 99 | (type == CHOICE_WEIGHTS) || |
|---|
| 100 | (type == TEXTFIELD)) |
|---|
| 101 | { |
|---|
| 102 | char *awarname=GDE_makeawarname(gmenuitem, number); |
|---|
| 103 | method=awr->awar(awarname)->read_string(); |
|---|
| 104 | textvalue=awr->awar(awarname)->read_string(); |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | if (textvalue == NULL) textvalue=(char *)calloc(1, sizeof(char)); |
|---|
| 108 | if (method == NULL) method=(char *)calloc(1, sizeof(char)); |
|---|
| 109 | if (symbol == NULL) symbol=""; |
|---|
| 110 | |
|---|
| 111 | set<string>warned_about; |
|---|
| 112 | int conversion_warning = 0; |
|---|
| 113 | int j = 0; |
|---|
| 114 | |
|---|
| 115 | for (; (i=Find2(Action+j, symbol)) != -1;) |
|---|
| 116 | { |
|---|
| 117 | i += j; |
|---|
| 118 | ++j; |
|---|
| 119 | if (i>0 && Action[i-1] == '$') |
|---|
| 120 | { |
|---|
| 121 | newlen = strlen(Action)-strlen(symbol) |
|---|
| 122 | +strlen(textvalue); |
|---|
| 123 | temp = (char *)calloc(newlen, 1); |
|---|
| 124 | if (temp == NULL) |
|---|
| 125 | Error("ReplaceArgs():Error in calloc"); |
|---|
| 126 | strncat(temp, Action, i-1); |
|---|
| 127 | strncat(temp, textvalue, strlen(textvalue)); |
|---|
| 128 | strcat(temp, &(Action[i+strlen(symbol)])); |
|---|
| 129 | freeset(Action, temp); |
|---|
| 130 | } |
|---|
| 131 | else { |
|---|
| 132 | if (warned_about.find(symbol) == warned_about.end()) { |
|---|
| 133 | fprintf(stderr, |
|---|
| 134 | "old arb version converted '%s' to '%s' (now only '$%s' is converted)\n", |
|---|
| 135 | symbol, textvalue, symbol); |
|---|
| 136 | conversion_warning++; |
|---|
| 137 | warned_about.insert(symbol); |
|---|
| 138 | } |
|---|
| 139 | } |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | if (conversion_warning) { |
|---|
| 143 | fprintf(stderr, |
|---|
| 144 | "Conversion warnings occurred in Action:\n'%s'\n", |
|---|
| 145 | Action); |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | free(textvalue); |
|---|
| 149 | free(method); |
|---|
| 150 | return (Action); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | |
|---|
| 155 | static long LMAX(long a, long b) |
|---|
| 156 | { |
|---|
| 157 | if (a>b) return a; |
|---|
| 158 | return b; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | static void GDE_free(void **p) { |
|---|
| 162 | freenull(*p); |
|---|
| 163 | } |
|---|
| 164 | |
|---|
| 165 | static char *ReplaceFile(char *Action, GfileFormat file) |
|---|
| 166 | { |
|---|
| 167 | char *symbol, *method, *temp; |
|---|
| 168 | int i, newlen; |
|---|
| 169 | symbol = file.symbol; |
|---|
| 170 | method = file.name; |
|---|
| 171 | |
|---|
| 172 | for (; (i=Find2(Action, symbol)) != -1;) |
|---|
| 173 | { |
|---|
| 174 | newlen = strlen(Action)-strlen(symbol) + strlen(method)+1; |
|---|
| 175 | temp = (char *)calloc(newlen, 1); |
|---|
| 176 | if (temp == NULL) |
|---|
| 177 | Error("ReplaceFile():Error in calloc"); |
|---|
| 178 | strncat(temp, Action, i); |
|---|
| 179 | strncat(temp, method, strlen(method)); |
|---|
| 180 | strcat(temp, &(Action[i+strlen(symbol)])); |
|---|
| 181 | freeset(Action, temp); |
|---|
| 182 | } |
|---|
| 183 | return (Action); |
|---|
| 184 | } |
|---|
| 185 | |
|---|
| 186 | static char *ReplaceString(char *Action, const char *old, const char *news) |
|---|
| 187 | { |
|---|
| 188 | const char *symbol; |
|---|
| 189 | const char *method; |
|---|
| 190 | char *temp; |
|---|
| 191 | int i, newlen; |
|---|
| 192 | |
|---|
| 193 | symbol = old; |
|---|
| 194 | method = news; |
|---|
| 195 | |
|---|
| 196 | for (; (i=Find2(Action, symbol)) != -1;) |
|---|
| 197 | { |
|---|
| 198 | newlen = strlen(Action)-strlen(symbol) + strlen(method)+1; |
|---|
| 199 | temp = (char *)calloc(newlen, 1); |
|---|
| 200 | if (temp == NULL) |
|---|
| 201 | Error("ReplaceFile():Error in calloc"); |
|---|
| 202 | strncat(temp, Action, i); |
|---|
| 203 | strncat(temp, method, strlen(method)); |
|---|
| 204 | strcat(temp, &(Action[i+strlen(symbol)])); |
|---|
| 205 | freeset(Action, temp); |
|---|
| 206 | } |
|---|
| 207 | return (Action); |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | |
|---|
| 211 | static void GDE_freesequ(NA_Sequence *sequ) { |
|---|
| 212 | if (sequ) { |
|---|
| 213 | GDE_free((void**)&sequ->comments); |
|---|
| 214 | GDE_free((void**)&sequ->cmask); |
|---|
| 215 | GDE_free((void**)&sequ->baggage); |
|---|
| 216 | GDE_free((void**)&sequ->sequence); |
|---|
| 217 | } |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | static void GDE_freeali(NA_Alignment *dataset) { |
|---|
| 221 | if (dataset) { |
|---|
| 222 | GDE_free((void**)&dataset->id); |
|---|
| 223 | GDE_free((void**)&dataset->description); |
|---|
| 224 | GDE_free((void**)&dataset->authority); |
|---|
| 225 | GDE_free((void**)&dataset->cmask); |
|---|
| 226 | GDE_free((void**)&dataset->selection_mask); |
|---|
| 227 | GDE_free((void**)&dataset->alignment_name); |
|---|
| 228 | |
|---|
| 229 | for (unsigned long i=0; i<dataset->numelements; i++) { |
|---|
| 230 | GDE_freesequ(dataset->element+i); |
|---|
| 231 | } |
|---|
| 232 | } |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | static void GDE_export(NA_Alignment *dataset, char *align, long oldnumelements) { |
|---|
| 236 | GBDATA *gb_main = db_access.gb_main; |
|---|
| 237 | GB_ERROR error = GB_begin_transaction(gb_main); |
|---|
| 238 | |
|---|
| 239 | long maxalignlen = GBT_get_alignment_len(gb_main, align); |
|---|
| 240 | long isdefaultalign = 0; |
|---|
| 241 | |
|---|
| 242 | if (maxalignlen <= 0 && !error) { |
|---|
| 243 | GB_clear_error(); // clear "alignment not found" error |
|---|
| 244 | |
|---|
| 245 | align = GBT_get_default_alignment(gb_main); |
|---|
| 246 | if (!align) error = GB_await_error(); |
|---|
| 247 | else { |
|---|
| 248 | isdefaultalign = 1; |
|---|
| 249 | maxalignlen = GBT_get_alignment_len(gb_main, align); |
|---|
| 250 | } |
|---|
| 251 | } |
|---|
| 252 | |
|---|
| 253 | long lotyp = 0; |
|---|
| 254 | if (!error) { |
|---|
| 255 | GB_alignment_type at = GBT_get_alignment_type(gb_main, align); |
|---|
| 256 | |
|---|
| 257 | switch (at) { |
|---|
| 258 | case GB_AT_DNA: lotyp = DNA; break; |
|---|
| 259 | case GB_AT_RNA: lotyp = RNA; break; |
|---|
| 260 | case GB_AT_AA: lotyp = PROTEIN; break; |
|---|
| 261 | case GB_AT_UNKNOWN: lotyp = DNA; break; |
|---|
| 262 | } |
|---|
| 263 | } |
|---|
| 264 | |
|---|
| 265 | unsigned long i; |
|---|
| 266 | |
|---|
| 267 | AW_repeated_question overwrite_question; |
|---|
| 268 | AW_repeated_question checksum_change_question; |
|---|
| 269 | |
|---|
| 270 | arb_progress progress("importing", dataset->numelements-oldnumelements+1); // +1 avoids zero-progress |
|---|
| 271 | for (i = oldnumelements; !error && i < dataset->numelements; i++) { |
|---|
| 272 | NA_Sequence *sequ = dataset->element+i; |
|---|
| 273 | int seqtyp, issame = 0; |
|---|
| 274 | |
|---|
| 275 | seqtyp = sequ->elementtype; |
|---|
| 276 | if ((seqtyp == lotyp) || ((seqtyp == DNA) && (lotyp == RNA)) || ((seqtyp == RNA) && (lotyp == DNA))) { |
|---|
| 277 | issame = 1; |
|---|
| 278 | } |
|---|
| 279 | else { |
|---|
| 280 | aw_message(GBS_global_string("Warning: sequence type of species '%s' changed", sequ->short_name)); |
|---|
| 281 | } |
|---|
| 282 | |
|---|
| 283 | if (sequ->tmatrix) { |
|---|
| 284 | for (long j = 0; j < sequ->seqlen; j++) { |
|---|
| 285 | sequ->sequence[j] = (char)sequ->tmatrix[sequ->sequence[j]]; |
|---|
| 286 | } |
|---|
| 287 | sequ->sequence[sequ->seqlen] = 0; |
|---|
| 288 | } |
|---|
| 289 | |
|---|
| 290 | char *savename = GBS_string_2_key(sequ->short_name); |
|---|
| 291 | |
|---|
| 292 | sequ->gb_species = 0; |
|---|
| 293 | |
|---|
| 294 | const char *new_seq = (const char *)sequ->sequence; |
|---|
| 295 | gde_assert(new_seq[sequ->seqlen] == 0); |
|---|
| 296 | gde_assert((int)strlen(new_seq) == sequ->seqlen); |
|---|
| 297 | |
|---|
| 298 | if (!issame) { // save as extended |
|---|
| 299 | GBDATA *gb_extended = GBT_find_or_create_SAI(db_access.gb_main, savename); |
|---|
| 300 | |
|---|
| 301 | if (!gb_extended) error = GB_await_error(); |
|---|
| 302 | else { |
|---|
| 303 | sequ->gb_species = gb_extended; |
|---|
| 304 | GBDATA *gb_data = GBT_add_data(gb_extended, align, "data", GB_STRING); |
|---|
| 305 | |
|---|
| 306 | if (!gb_data) error = GB_await_error(); |
|---|
| 307 | else error = GBT_write_sequence(gb_data, align, maxalignlen, new_seq); |
|---|
| 308 | } |
|---|
| 309 | } |
|---|
| 310 | else { // save as sequence |
|---|
| 311 | GBDATA *gb_species_data = GBT_get_species_data(db_access.gb_main); |
|---|
| 312 | if (!gb_species_data) error = GB_await_error(); |
|---|
| 313 | else { |
|---|
| 314 | GBDATA *gb_species = GBT_find_species_rel_species_data(gb_species_data, savename); |
|---|
| 315 | |
|---|
| 316 | GB_push_my_security(db_access.gb_main); |
|---|
| 317 | |
|---|
| 318 | if (gb_species) { // new element that already exists !!!! |
|---|
| 319 | const char *question = |
|---|
| 320 | GBS_global_string("You are (re-)importing a species '%s'.\n" |
|---|
| 321 | "That species already exists in your database!\n" |
|---|
| 322 | "\n" |
|---|
| 323 | "Possible actions:\n" |
|---|
| 324 | "\n" |
|---|
| 325 | " - overwrite existing species (all fields)\n" |
|---|
| 326 | " - overwrite the sequence (does not change other fields)\n" |
|---|
| 327 | " - skip import of the species\n" |
|---|
| 328 | "\n" |
|---|
| 329 | "Note: After aligning it's recommended to choose 'overwrite sequence'.", |
|---|
| 330 | savename); |
|---|
| 331 | |
|---|
| 332 | |
|---|
| 333 | enum ReplaceMode { REPLACE_SPEC = 0, REIMPORT_SEQ = 1, SKIP_IMPORT = 2, } |
|---|
| 334 | replace_mode = (ReplaceMode)overwrite_question.get_answer("GDE_overwrite", question, "Overwrite species,Overwrite sequence only,Skip entry", "all", false); |
|---|
| 335 | |
|---|
| 336 | switch (replace_mode) { |
|---|
| 337 | case SKIP_IMPORT: |
|---|
| 338 | gb_species = 0; |
|---|
| 339 | break; |
|---|
| 340 | case REPLACE_SPEC: |
|---|
| 341 | error = GB_delete(gb_species); |
|---|
| 342 | gb_species = NULL; |
|---|
| 343 | if (error) break; |
|---|
| 344 | // fall-through |
|---|
| 345 | case REIMPORT_SEQ: |
|---|
| 346 | gb_species = GBT_find_or_create_species_rel_species_data(gb_species_data, savename); |
|---|
| 347 | if (!gb_species) error = GB_await_error(); |
|---|
| 348 | break; |
|---|
| 349 | } |
|---|
| 350 | } |
|---|
| 351 | else { |
|---|
| 352 | gb_species = GBT_find_or_create_species_rel_species_data(gb_species_data, savename); |
|---|
| 353 | if (!gb_species) error = GB_await_error(); |
|---|
| 354 | } |
|---|
| 355 | |
|---|
| 356 | if (gb_species) { |
|---|
| 357 | gde_assert(!error); |
|---|
| 358 | sequ->gb_species = gb_species; |
|---|
| 359 | |
|---|
| 360 | GBDATA *gb_data = GBT_add_data(gb_species, align, "data", GB_STRING); // does only add if not already existing |
|---|
| 361 | if (!gb_data) error = GB_await_error(); |
|---|
| 362 | else { |
|---|
| 363 | GBDATA *gb_old_data = GBT_read_sequence(gb_species, align); |
|---|
| 364 | bool writeSequence = true; |
|---|
| 365 | if (gb_old_data) { // we already have data -> compare checksums |
|---|
| 366 | const char *old_seq = GB_read_char_pntr(gb_old_data); |
|---|
| 367 | long old_checksum = GBS_checksum(old_seq, 1, "-."); |
|---|
| 368 | long new_checksum = GBS_checksum(new_seq, 1, "-."); |
|---|
| 369 | |
|---|
| 370 | if (old_checksum != new_checksum) { |
|---|
| 371 | const char *question = GBS_global_string("Warning: Sequence checksum of '%s' has changed\n", savename); |
|---|
| 372 | enum ChangeMode { |
|---|
| 373 | ACCEPT_CHANGE = 0, |
|---|
| 374 | REJECT_CHANGE = 1, |
|---|
| 375 | } change_mode = (ChangeMode)checksum_change_question.get_answer("GDE_accept", question, "Accept change,Reject", "all", false); |
|---|
| 376 | |
|---|
| 377 | if (change_mode == REJECT_CHANGE) writeSequence = false; |
|---|
| 378 | |
|---|
| 379 | aw_message(GBS_global_string("Warning: Sequence checksum for '%s' has changed (%s)", |
|---|
| 380 | savename, writeSequence ? "accepted" : "rejected")); |
|---|
| 381 | } |
|---|
| 382 | } |
|---|
| 383 | if (writeSequence) { |
|---|
| 384 | error = GBT_write_sequence(gb_data, align, maxalignlen, new_seq); |
|---|
| 385 | } |
|---|
| 386 | } |
|---|
| 387 | } |
|---|
| 388 | GB_pop_my_security(db_access.gb_main); |
|---|
| 389 | } |
|---|
| 390 | } |
|---|
| 391 | free(savename); |
|---|
| 392 | progress.inc_and_check_user_abort(error); |
|---|
| 393 | } |
|---|
| 394 | |
|---|
| 395 | // colormasks |
|---|
| 396 | for (i = 0; !error && i < dataset->numelements; i++) { |
|---|
| 397 | NA_Sequence *sequ = &(dataset->element[i]); |
|---|
| 398 | |
|---|
| 399 | if (sequ->cmask) { |
|---|
| 400 | maxalignlen = LMAX(maxalignlen, sequ->seqlen); |
|---|
| 401 | char *resstring = (char *)calloc((unsigned int)maxalignlen + 1, sizeof(char)); |
|---|
| 402 | char *dummy = resstring; |
|---|
| 403 | |
|---|
| 404 | for (long j = 0; j < maxalignlen - sequ->seqlen; j++) *resstring++ = DEFAULT_COLOR; |
|---|
| 405 | for (long k = 0; k < sequ->seqlen; k++) *resstring++ = (char)sequ->cmask[i]; |
|---|
| 406 | *resstring = '\0'; |
|---|
| 407 | |
|---|
| 408 | GBDATA *gb_ali = GB_search(sequ->gb_species, align, GB_CREATE_CONTAINER); |
|---|
| 409 | if (!gb_ali) error = GB_await_error(); |
|---|
| 410 | else { |
|---|
| 411 | GBDATA *gb_color = GB_search(gb_ali, "colmask", GB_BYTES); |
|---|
| 412 | if (!gb_color) error = GB_await_error(); |
|---|
| 413 | else error = GB_write_bytes(gb_color, dummy, maxalignlen); |
|---|
| 414 | } |
|---|
| 415 | free(dummy); |
|---|
| 416 | } |
|---|
| 417 | } |
|---|
| 418 | |
|---|
| 419 | if (!error && dataset->cmask) { |
|---|
| 420 | maxalignlen = LMAX(maxalignlen, dataset->cmask_len); |
|---|
| 421 | char *resstring = (char *)calloc((unsigned int)maxalignlen + 1, sizeof(char)); |
|---|
| 422 | char *dummy = resstring; |
|---|
| 423 | long k; |
|---|
| 424 | |
|---|
| 425 | for (k = 0; k < maxalignlen - dataset->cmask_len; k++) *resstring++ = DEFAULT_COLOR; |
|---|
| 426 | for (k = 0; k < dataset->cmask_len; k++) *resstring++ = (char)dataset->cmask[k]; |
|---|
| 427 | *resstring = '\0'; |
|---|
| 428 | |
|---|
| 429 | GBDATA *gb_extended = GBT_find_or_create_SAI(db_access.gb_main, "COLMASK"); |
|---|
| 430 | if (!gb_extended) error = GB_await_error(); |
|---|
| 431 | else { |
|---|
| 432 | GBDATA *gb_color = GBT_add_data(gb_extended, align, "colmask", GB_BYTES); |
|---|
| 433 | if (!gb_color) error = GB_await_error(); |
|---|
| 434 | else error = GB_write_bytes(gb_color, dummy, maxalignlen); |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | free(dummy); |
|---|
| 438 | } |
|---|
| 439 | |
|---|
| 440 | progress.done(); |
|---|
| 441 | |
|---|
| 442 | GB_end_transaction_show_error(db_access.gb_main, error, aw_message); |
|---|
| 443 | if (isdefaultalign) free(align); |
|---|
| 444 | } |
|---|
| 445 | |
|---|
| 446 | static char *preCreateTempfile(const char *name) { |
|---|
| 447 | // creates a tempfile and returns heapcopy of fullpath |
|---|
| 448 | // exits in case of error |
|---|
| 449 | char *fullname = GB_create_tempfile(name); |
|---|
| 450 | |
|---|
| 451 | if (!fullname) Error(GBS_global_string("preCreateTempfile: %s", GB_await_error())); // exits |
|---|
| 452 | return fullname; |
|---|
| 453 | } |
|---|
| 454 | |
|---|
| 455 | void GDE_startaction_cb(AW_window *aw, GmenuItem *gmenuitem, AW_CL /*cd*/) { |
|---|
| 456 | long oldnumelements=0; |
|---|
| 457 | AW_root *aw_root=aw->get_root(); |
|---|
| 458 | |
|---|
| 459 | GapCompression compress = static_cast<GapCompression>(aw_root->awar(AWAR_GDE_COMPRESSION)->read_int()); |
|---|
| 460 | AP_filter *filter2 = awt_get_filter(agde_filtercd); |
|---|
| 461 | char *filter_name = 0; // aw_root->awar(AWAR_GDE_FILTER_NAME)->read_string() |
|---|
| 462 | char *alignment_name = strdup("ali_unknown"); |
|---|
| 463 | bool marked = (aw_root->awar(AWAR_GDE_SPECIES)->read_int() != 0); |
|---|
| 464 | long cutoff_stop_codon = aw_root->awar(AWAR_GDE_CUTOFF_STOPCODON)->read_int(); |
|---|
| 465 | GmenuItem *current_item = gmenuitem; |
|---|
| 466 | arb_progress progress(current_item->label); |
|---|
| 467 | |
|---|
| 468 | int j; |
|---|
| 469 | bool flag; |
|---|
| 470 | char *Action, buffer[GBUFSIZ]; |
|---|
| 471 | |
|---|
| 472 | static int fileindx = 0; |
|---|
| 473 | int select_mode = 0; |
|---|
| 474 | int stop = 0; |
|---|
| 475 | |
|---|
| 476 | if (current_item->numinputs>0) { |
|---|
| 477 | DataSet->gb_main = db_access.gb_main; |
|---|
| 478 | GB_begin_transaction(DataSet->gb_main); |
|---|
| 479 | freeset(DataSet->alignment_name, GBT_get_default_alignment(DataSet->gb_main)); |
|---|
| 480 | freedup(alignment_name, DataSet->alignment_name); |
|---|
| 481 | |
|---|
| 482 | progress.subtitle("reading database"); |
|---|
| 483 | if (db_access.get_sequences) { |
|---|
| 484 | stop = ReadArbdb2(DataSet, filter2, compress, cutoff_stop_codon); |
|---|
| 485 | } |
|---|
| 486 | else { |
|---|
| 487 | stop = ReadArbdb(DataSet, marked, filter2, compress, cutoff_stop_codon); |
|---|
| 488 | } |
|---|
| 489 | GB_commit_transaction(DataSet->gb_main); |
|---|
| 490 | |
|---|
| 491 | if (!stop && DataSet->numelements==0) { |
|---|
| 492 | aw_message("no sequences selected"); |
|---|
| 493 | stop = 1; |
|---|
| 494 | } |
|---|
| 495 | } |
|---|
| 496 | |
|---|
| 497 | if (!stop) { |
|---|
| 498 | flag = false; |
|---|
| 499 | for (j=0; j<current_item->numinputs; j++) { |
|---|
| 500 | if (current_item->input[j].format != STATUS_FILE) { |
|---|
| 501 | flag = true; |
|---|
| 502 | } |
|---|
| 503 | } |
|---|
| 504 | if (flag && DataSet) select_mode = ALL; |
|---|
| 505 | |
|---|
| 506 | int pid = getpid(); |
|---|
| 507 | |
|---|
| 508 | for (j=0; j<current_item->numinputs; j++) { |
|---|
| 509 | GfileFormat& gfile = current_item->input[j]; |
|---|
| 510 | |
|---|
| 511 | sprintf(buffer, "gde%d_%d", pid, fileindx++); |
|---|
| 512 | gfile.name = preCreateTempfile(buffer); |
|---|
| 513 | |
|---|
| 514 | switch (gfile.format) { |
|---|
| 515 | case COLORMASK: WriteCMask (DataSet, gfile.name, select_mode, gfile.maskable); break; |
|---|
| 516 | case GENBANK: WriteGen (DataSet, gfile.name, select_mode, gfile.maskable); break; |
|---|
| 517 | case NA_FLAT: WriteNA_Flat(DataSet, gfile.name, select_mode, gfile.maskable); break; |
|---|
| 518 | case STATUS_FILE: WriteStatus (DataSet, gfile.name); break; |
|---|
| 519 | case GDE: WriteGDE (DataSet, gfile.name, select_mode, gfile.maskable); break; |
|---|
| 520 | default: break; |
|---|
| 521 | } |
|---|
| 522 | } |
|---|
| 523 | |
|---|
| 524 | for (j=0; j<current_item->numoutputs; j++) { |
|---|
| 525 | sprintf(buffer, "gde%d_%d", pid, fileindx++); |
|---|
| 526 | current_item->output[j].name = preCreateTempfile(buffer); |
|---|
| 527 | } |
|---|
| 528 | |
|---|
| 529 | // Create the command line for external the function call |
|---|
| 530 | Action = (char*)strdup(current_item->method); |
|---|
| 531 | if (Action == NULL) Error("DO(): Error in duplicating method string"); |
|---|
| 532 | |
|---|
| 533 | while (1) { |
|---|
| 534 | char *oldAction = strdup(Action); |
|---|
| 535 | |
|---|
| 536 | for (j=0; j<current_item->numargs; j++) Action = ReplaceArgs(aw_root, Action, gmenuitem, j); |
|---|
| 537 | bool changed = strcmp(oldAction, Action) != 0; |
|---|
| 538 | free(oldAction); |
|---|
| 539 | |
|---|
| 540 | if (!changed) break; |
|---|
| 541 | } |
|---|
| 542 | |
|---|
| 543 | for (j=0; j<current_item->numinputs; j++) Action = ReplaceFile(Action, current_item->input[j]); |
|---|
| 544 | for (j=0; j<current_item->numoutputs; j++) Action = ReplaceFile(Action, current_item->output[j]); |
|---|
| 545 | |
|---|
| 546 | filter_name = AWT_get_combined_filter_name(aw_root, "gde"); |
|---|
| 547 | Action = ReplaceString(Action, "$FILTER", filter_name); |
|---|
| 548 | |
|---|
| 549 | // call and go... |
|---|
| 550 | progress.subtitle("calling external program"); |
|---|
| 551 | aw_message_if(GBK_system(Action)); |
|---|
| 552 | free(Action); |
|---|
| 553 | |
|---|
| 554 | oldnumelements=DataSet->numelements; |
|---|
| 555 | |
|---|
| 556 | BlockInput = false; |
|---|
| 557 | |
|---|
| 558 | for (j=0; j<current_item->numoutputs; j++) |
|---|
| 559 | { |
|---|
| 560 | if (current_item->output[j].overwrite) |
|---|
| 561 | { |
|---|
| 562 | if (current_item->output[j].format == GDE) |
|---|
| 563 | OVERWRITE = true; |
|---|
| 564 | else |
|---|
| 565 | Warning("Overwrite mode only available for GDE format"); |
|---|
| 566 | } |
|---|
| 567 | switch (current_item->output[j].format) |
|---|
| 568 | { |
|---|
| 569 | /* The LoadData routine must be reworked so that |
|---|
| 570 | * OpenFileName uses it, and so I can remove the |
|---|
| 571 | * major kluge in OpenFileName(). |
|---|
| 572 | */ |
|---|
| 573 | case GENBANK: |
|---|
| 574 | case NA_FLAT: |
|---|
| 575 | case GDE: |
|---|
| 576 | LoadData(current_item->output[j].name); |
|---|
| 577 | break; |
|---|
| 578 | case COLORMASK: |
|---|
| 579 | ReadCMask(current_item->output[j].name); |
|---|
| 580 | break; |
|---|
| 581 | default: |
|---|
| 582 | break; |
|---|
| 583 | } |
|---|
| 584 | OVERWRITE = false; |
|---|
| 585 | } |
|---|
| 586 | for (j=0; j<current_item->numoutputs; j++) |
|---|
| 587 | { |
|---|
| 588 | if (!current_item->output[j].save) |
|---|
| 589 | { |
|---|
| 590 | unlink(current_item->output[j].name); |
|---|
| 591 | } |
|---|
| 592 | } |
|---|
| 593 | |
|---|
| 594 | for (j=0; j<current_item->numinputs; j++) |
|---|
| 595 | { |
|---|
| 596 | if (!current_item->input[j].save) |
|---|
| 597 | { |
|---|
| 598 | unlink(current_item->input[j].name); |
|---|
| 599 | } |
|---|
| 600 | } |
|---|
| 601 | |
|---|
| 602 | GDE_export(DataSet, alignment_name, oldnumelements); |
|---|
| 603 | } |
|---|
| 604 | |
|---|
| 605 | free(alignment_name); |
|---|
| 606 | delete filter2; |
|---|
| 607 | free(filter_name); |
|---|
| 608 | |
|---|
| 609 | GDE_freeali(DataSet); |
|---|
| 610 | freeset(DataSet, (NA_Alignment *)Calloc(1, sizeof(NA_Alignment))); |
|---|
| 611 | DataSet->rel_offset = 0; |
|---|
| 612 | } |
|---|