| 1 | // ================================================================ // |
|---|
| 2 | // // |
|---|
| 3 | // File : MP_Window.cxx // |
|---|
| 4 | // Purpose : // |
|---|
| 5 | // // |
|---|
| 6 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 7 | // http://www.arb-home.de/ // |
|---|
| 8 | // // |
|---|
| 9 | // ================================================================ // |
|---|
| 10 | |
|---|
| 11 | #include "MP_externs.hxx" |
|---|
| 12 | #include "MultiProbe.hxx" |
|---|
| 13 | #include "mp_proto.hxx" |
|---|
| 14 | |
|---|
| 15 | #include <awt_sel_boxes.hxx> |
|---|
| 16 | #include <awt_modules.hxx> |
|---|
| 17 | #include <aw_select.hxx> |
|---|
| 18 | #include <aw_file.hxx> |
|---|
| 19 | #include <aw_msg.hxx> |
|---|
| 20 | #include <aw_root.hxx> |
|---|
| 21 | #include <aw_awar_defs.hxx> |
|---|
| 22 | |
|---|
| 23 | #include <arb_strarray.h> |
|---|
| 24 | #include <arb_defs.h> |
|---|
| 25 | #include <arb_strbuf.h> |
|---|
| 26 | #include <arbdbt.h> |
|---|
| 27 | #include <ad_cb.h> |
|---|
| 28 | #include <RegExpr.hxx> |
|---|
| 29 | |
|---|
| 30 | // ************************************************************************** |
|---|
| 31 | |
|---|
| 32 | AW_selection_list *selected_list; |
|---|
| 33 | AW_selection_list *result_probes_list; |
|---|
| 34 | |
|---|
| 35 | static AW_selection_list *probelist; |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | AW_window_simple *MP_Window::create_result_window(AW_root *aw_root) { |
|---|
| 39 | if (!result_window) { |
|---|
| 40 | result_window = new AW_window_simple; |
|---|
| 41 | result_window->init(aw_root, "MULTIPROBE_RESULTS", "MultiProbe combination results"); |
|---|
| 42 | result_window->load_xfig("mp_results.fig"); |
|---|
| 43 | |
|---|
| 44 | result_window->auto_space(5, 5); |
|---|
| 45 | |
|---|
| 46 | result_window->button_length(7); |
|---|
| 47 | result_window->at("close"); |
|---|
| 48 | result_window->callback(AW_POPDOWN); |
|---|
| 49 | result_window->create_button("CLOSE", "CLOSE"); |
|---|
| 50 | |
|---|
| 51 | result_window->at("Help"); |
|---|
| 52 | result_window->callback(makeHelpCallback("multiproberesults.hlp")); |
|---|
| 53 | result_window->create_button("HELP", "HELP"); |
|---|
| 54 | |
|---|
| 55 | result_window->at("Comment"); |
|---|
| 56 | result_window->callback(makeWindowCallback(MP_Comment, (const char *)NULp)); |
|---|
| 57 | result_window->create_input_field(MP_AWAR_RESULTPROBESCOMMENT); |
|---|
| 58 | |
|---|
| 59 | result_window->at("box"); |
|---|
| 60 | aw_root->awar(MP_AWAR_RESULTPROBES)->add_callback(MP_result_combination_chosen); |
|---|
| 61 | result_probes_list = result_window->create_selection_list(MP_AWAR_RESULTPROBES); |
|---|
| 62 | result_probes_list->set_file_suffix("mpr"); |
|---|
| 63 | result_probes_list->insert_default("", ""); |
|---|
| 64 | |
|---|
| 65 | const StorableSelectionList *storable_probes_list = new StorableSelectionList(TypedSelectionList("mpr", result_probes_list, "multiprobes", "multi_probes")); |
|---|
| 66 | |
|---|
| 67 | result_window->at("buttons"); |
|---|
| 68 | result_window->callback(makeCreateWindowCallback(create_load_box_for_selection_lists, storable_probes_list)); |
|---|
| 69 | result_window->create_button("LOAD_RPL", "LOAD"); |
|---|
| 70 | |
|---|
| 71 | result_window->callback(makeCreateWindowCallback(create_save_box_for_selection_lists, storable_probes_list)); |
|---|
| 72 | result_window->create_button("SAVE_RPL", "SAVE"); |
|---|
| 73 | |
|---|
| 74 | result_window->callback(makeWindowCallback(awt_clear_selection_list_cb, result_probes_list)); |
|---|
| 75 | result_window->create_button("CLEAR", "CLEAR"); |
|---|
| 76 | |
|---|
| 77 | result_window->callback(makeWindowCallback(MP_delete_selected, result_probes_list)); |
|---|
| 78 | result_window->create_button("DELETE", "DELETE"); |
|---|
| 79 | |
|---|
| 80 | // change comment : |
|---|
| 81 | |
|---|
| 82 | result_window->button_length(8); |
|---|
| 83 | |
|---|
| 84 | result_window->at("comment"); |
|---|
| 85 | result_window->callback(makeWindowCallback(MP_Comment, "Bad")); |
|---|
| 86 | result_window->create_button("MARK_AS_BAD", "BAD"); |
|---|
| 87 | |
|---|
| 88 | result_window->callback(makeWindowCallback(MP_Comment, "???")); |
|---|
| 89 | result_window->create_button("MARK_AS_GOOD", "???"); |
|---|
| 90 | |
|---|
| 91 | result_window->callback(makeWindowCallback(MP_Comment, "Good")); |
|---|
| 92 | result_window->create_button("MARK_AS_BEST", "Good"); |
|---|
| 93 | |
|---|
| 94 | result_window->at("auto"); |
|---|
| 95 | result_window->create_toggle(MP_AWAR_AUTOADVANCE); |
|---|
| 96 | |
|---|
| 97 | // tree actions : |
|---|
| 98 | |
|---|
| 99 | result_window->button_length(3); |
|---|
| 100 | |
|---|
| 101 | result_window->at("ct_back"); |
|---|
| 102 | result_window->callback(makeWindowCallback(MP_show_probes_in_tree_move, true, result_probes_list)); |
|---|
| 103 | result_window->create_button("COLOR_TREE_BACKWARD", "#rightleft_small.xpm"); |
|---|
| 104 | |
|---|
| 105 | result_window->at("ct_fwd"); |
|---|
| 106 | result_window->callback(makeWindowCallback(MP_show_probes_in_tree_move, false, result_probes_list)); |
|---|
| 107 | result_window->create_button("COLOR_TREE_FORWARD", "#leftright_small.xpm"); |
|---|
| 108 | |
|---|
| 109 | result_window->button_length(8); |
|---|
| 110 | |
|---|
| 111 | result_window->at("ColorTree"); |
|---|
| 112 | result_window->button_length(4); |
|---|
| 113 | result_window->callback(MP_show_probes_in_tree); |
|---|
| 114 | result_window->create_button("COLOR_TREE", "GO"); |
|---|
| 115 | |
|---|
| 116 | result_window->at("MarkTree"); |
|---|
| 117 | result_window->callback(MP_mark_probes_in_tree); |
|---|
| 118 | result_window->create_button("MARK_TREE", "GO"); |
|---|
| 119 | |
|---|
| 120 | result_window->at("GroupAll"); |
|---|
| 121 | result_window->callback(MP_group_all_except_marked); |
|---|
| 122 | result_window->create_button("GROUP_UNMARKED", "GO"); |
|---|
| 123 | |
|---|
| 124 | result_window->at("StandardColor"); |
|---|
| 125 | result_window->callback(MP_normal_colors_in_tree); |
|---|
| 126 | result_window->create_button("RESET_COLORS", "GO"); |
|---|
| 127 | } |
|---|
| 128 | return result_window; |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | // -------------------------------------------------------------------------------- |
|---|
| 132 | // Format of probe-list for multi-probes: |
|---|
| 133 | // |
|---|
| 134 | // The saved format is identical to the internal format (of sellist entries; where value always equals displayed!) |
|---|
| 135 | // "quality#singlemismatch#ecolipos#target" |
|---|
| 136 | // |
|---|
| 137 | // When loading input probes, several other formats are accepted: |
|---|
| 138 | // |
|---|
| 139 | // "quality,singlemismatch#ecolipos#probe" (old save format) |
|---|
| 140 | // "target le pos apos ecol grps GC 4gc2at probe | ..." (save of probe design; old format) |
|---|
| 141 | // "target le pos apos ecol grps GC 4gc2at probe | ...,target" (save of probe design) |
|---|
| 142 | // |
|---|
| 143 | // above |
|---|
| 144 | // 'target' is the target-string of the 'probe'. Internally MP works with target strings, |
|---|
| 145 | // so when loading the old save-format, 'probe' gets reverse-complemented into 'target' |
|---|
| 146 | |
|---|
| 147 | |
|---|
| 148 | #define SPACED(expr) "[[:space:]]*" expr "[[:space:]]*" |
|---|
| 149 | |
|---|
| 150 | inline char *gen_display(int quality, int singleMis, int ecoliPos, const char *probe) { |
|---|
| 151 | return GBS_global_string_copy("%i#%i#%5i#%s", quality, singleMis, ecoliPos, probe); |
|---|
| 152 | } |
|---|
| 153 | |
|---|
| 154 | static GB_ERROR mp_list2file(const CharPtrArray& display, const CharPtrArray& value, StrArray& line) { |
|---|
| 155 | GB_ERROR error = NULp; |
|---|
| 156 | |
|---|
| 157 | if (value.empty()) error = "nothing to save"; |
|---|
| 158 | |
|---|
| 159 | for (size_t i = 0; i<display.size() && !error; ++i) { |
|---|
| 160 | line.put(ARB_strdup(display[i])); |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | return error; |
|---|
| 164 | } |
|---|
| 165 | |
|---|
| 166 | static char T_or_U_for_load = 0; |
|---|
| 167 | |
|---|
| 168 | static GB_ERROR mp_file2list(const CharPtrArray& line, StrArray& display, StrArray& value) { |
|---|
| 169 | GB_ERROR error = NULp; |
|---|
| 170 | |
|---|
| 171 | if (line.empty()) error = "empty file"; |
|---|
| 172 | |
|---|
| 173 | // detect format |
|---|
| 174 | if (!error) { |
|---|
| 175 | // 1. try to read probes saved from multiprobes inputlist |
|---|
| 176 | RegExpr reg_saved("^" SPACED("([0-9]+)") "([,#])" SPACED("([0-9])+") "#" SPACED("([0-9]+)") "#" SPACED("([A-Z]+)") "$", true); |
|---|
| 177 | bool isSavedFormat = true; |
|---|
| 178 | |
|---|
| 179 | for (size_t i = 0; i<line.size() && isSavedFormat; ++i) { |
|---|
| 180 | const RegMatch *match = reg_saved.match(line[i]); |
|---|
| 181 | if (!match || reg_saved.subexpr_count() != 5) { |
|---|
| 182 | isSavedFormat = false; |
|---|
| 183 | if (reg_saved.has_failed()) aw_message(reg_saved.get_error()); |
|---|
| 184 | } |
|---|
| 185 | else { |
|---|
| 186 | char T_or_U = T_or_U_for_load ? T_or_U_for_load : 'U'; |
|---|
| 187 | |
|---|
| 188 | std::string sep = reg_saved.subexpr_match(2)->extract(line[i]); |
|---|
| 189 | |
|---|
| 190 | int quality = atoi(reg_saved.subexpr_match(1)->extract(line[i]).c_str()); |
|---|
| 191 | int singlemis = atoi(reg_saved.subexpr_match(3)->extract(line[i]).c_str()); |
|---|
| 192 | int ecoli = atoi(reg_saved.subexpr_match(4)->extract(line[i]).c_str()); |
|---|
| 193 | |
|---|
| 194 | std::string probe = reg_saved.subexpr_match(5)->extract(line[i]); |
|---|
| 195 | |
|---|
| 196 | if (sep[0] == ',') { // old format (saved probe instead of probe-target) |
|---|
| 197 | size_t plen = probe.length(); |
|---|
| 198 | char *dprobe = ARB_strndup(probe.c_str(), plen); |
|---|
| 199 | |
|---|
| 200 | GBT_reverseComplementNucSequence(dprobe, plen, T_or_U); |
|---|
| 201 | probe = dprobe; |
|---|
| 202 | free(dprobe); |
|---|
| 203 | } |
|---|
| 204 | |
|---|
| 205 | char *entry = gen_display(quality, singlemis, ecoli, probe.c_str()); |
|---|
| 206 | display.put(entry); // transfers ownership - dont free! |
|---|
| 207 | value.put(ARB_strdup(entry)); |
|---|
| 208 | } |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | if (!isSavedFormat) { |
|---|
| 212 | // delete attempt to read saved format: |
|---|
| 213 | display.clear(); |
|---|
| 214 | value.clear(); |
|---|
| 215 | |
|---|
| 216 | // try to read designed list |
|---|
| 217 | RegExpr reg_designed("^([A-Z]+)" // subexpr #1 (target) |
|---|
| 218 | "[[:space:]]+[0-9]+" |
|---|
| 219 | "[[:space:]]+[A-Z][=+-]" |
|---|
| 220 | "[[:space:]]*[0-9]+" |
|---|
| 221 | "[[:space:]]+([0-9]+)" // subexpr #2 (ecoli pos) |
|---|
| 222 | "([[:space:]]+[0-9]+){1,2}" // accept with and without quality entry |
|---|
| 223 | "([[:space:]]+[0-9.]+){2}" |
|---|
| 224 | "[[:space:]]+[A-Z]+" |
|---|
| 225 | "[[:space:]]+[|]", true); |
|---|
| 226 | |
|---|
| 227 | for (size_t i = 0; i<line.size() && !error; ++i) { |
|---|
| 228 | char *probe = NULp; |
|---|
| 229 | char *description = NULp; |
|---|
| 230 | bool new_format = false; |
|---|
| 231 | |
|---|
| 232 | const char *comma = strchr(line[i], ','); |
|---|
| 233 | if (comma) { |
|---|
| 234 | description = ARB_strpartdup(line[i], comma-1); |
|---|
| 235 | |
|---|
| 236 | const char *cprobe = comma+1; |
|---|
| 237 | while (cprobe[0] == ' ') ++cprobe; |
|---|
| 238 | probe = ARB_strdup(cprobe); |
|---|
| 239 | |
|---|
| 240 | new_format = true; |
|---|
| 241 | } |
|---|
| 242 | else { |
|---|
| 243 | description = ARB_strdup(line[i]); |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | const RegMatch *match = reg_designed.match(description); |
|---|
| 247 | if (match) { // line from probe design (old + new format) |
|---|
| 248 | mp_assert(match->didMatch()); |
|---|
| 249 | |
|---|
| 250 | match = reg_designed.subexpr_match(1); |
|---|
| 251 | mp_assert(match->didMatch()); |
|---|
| 252 | std::string parsed_probe = match->extract(description); |
|---|
| 253 | |
|---|
| 254 | if (new_format) { // already got probe value -> compare |
|---|
| 255 | if (strcmp(probe, parsed_probe.c_str()) != 0) { |
|---|
| 256 | error = GBS_global_string("probe string mismatch (probe='%s', parsed_probe='%s', parsed from='%s')", |
|---|
| 257 | probe, parsed_probe.c_str(), line[i]); |
|---|
| 258 | } |
|---|
| 259 | } |
|---|
| 260 | else { |
|---|
| 261 | probe = ARB_strdup(parsed_probe.c_str()); |
|---|
| 262 | } |
|---|
| 263 | |
|---|
| 264 | if (!error) { |
|---|
| 265 | int quality, ecoli; |
|---|
| 266 | |
|---|
| 267 | match = reg_designed.subexpr_match(2); |
|---|
| 268 | mp_assert(match->didMatch()); |
|---|
| 269 | ecoli = atoi(match->extract(description).c_str()); |
|---|
| 270 | quality = 3; |
|---|
| 271 | |
|---|
| 272 | char *entry = gen_display(quality, 0, ecoli, probe); |
|---|
| 273 | display.put(entry); // transfers ownership - dont free! |
|---|
| 274 | value.put(ARB_strdup(entry)); |
|---|
| 275 | } |
|---|
| 276 | } |
|---|
| 277 | else { |
|---|
| 278 | if (reg_designed.has_failed()) aw_message(reg_designed.get_error()); |
|---|
| 279 | if (new_format && probe[0]) { |
|---|
| 280 | error = GBS_global_string("can't parse line '%s'", line[i]); |
|---|
| 281 | } |
|---|
| 282 | // (when loading old format -> silently ignore non-matching lines) |
|---|
| 283 | } |
|---|
| 284 | |
|---|
| 285 | free(probe); |
|---|
| 286 | free(description); |
|---|
| 287 | } |
|---|
| 288 | } |
|---|
| 289 | } |
|---|
| 290 | |
|---|
| 291 | return error; |
|---|
| 292 | } |
|---|
| 293 | |
|---|
| 294 | static void track_ali_change_cb(AW_root*, GBDATA *gb_main) { |
|---|
| 295 | GB_transaction ta(gb_main); |
|---|
| 296 | |
|---|
| 297 | char *aliname = GBT_get_default_alignment(gb_main); |
|---|
| 298 | if (!aliname) { |
|---|
| 299 | aw_message(GB_await_error()); |
|---|
| 300 | } |
|---|
| 301 | else { |
|---|
| 302 | GB_alignment_type alitype = GBT_get_alignment_type(gb_main, aliname); |
|---|
| 303 | mp_assert(alitype != GB_AT_UNKNOWN); |
|---|
| 304 | GBT_determine_T_or_U(alitype, &T_or_U_for_load, "reverse-complement"); // T_or_U_for_load is set to 0 in error-case |
|---|
| 305 | free(aliname); |
|---|
| 306 | } |
|---|
| 307 | } |
|---|
| 308 | |
|---|
| 309 | static void MP_collect_probes(AW_window*, awt_collect_mode mode) { |
|---|
| 310 | switch (mode) { |
|---|
| 311 | case ACM_ADD: |
|---|
| 312 | if (!probelist->default_is_selected()) { |
|---|
| 313 | int idx = probelist->get_index_of_selected(); |
|---|
| 314 | AW_selection_list_iterator sel(probelist, idx); |
|---|
| 315 | selected_list->insert(sel.get_displayed(), *sel.get_value()); |
|---|
| 316 | MP_delete_selected(NULp, probelist); |
|---|
| 317 | } |
|---|
| 318 | break; |
|---|
| 319 | |
|---|
| 320 | case ACM_REMOVE: |
|---|
| 321 | if (!selected_list->default_is_selected()) { |
|---|
| 322 | int idx = selected_list->get_index_of_selected(); |
|---|
| 323 | AW_selection_list_iterator sel(selected_list, idx); |
|---|
| 324 | probelist->insert(sel.get_displayed(), *sel.get_value()); |
|---|
| 325 | MP_delete_selected(NULp, selected_list); |
|---|
| 326 | } |
|---|
| 327 | break; |
|---|
| 328 | |
|---|
| 329 | case ACM_FILL: |
|---|
| 330 | probelist->move_content_to(selected_list); |
|---|
| 331 | break; |
|---|
| 332 | |
|---|
| 333 | case ACM_EMPTY: |
|---|
| 334 | selected_list->move_content_to(probelist); |
|---|
| 335 | break; |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | selected_list->sort(false, true); |
|---|
| 339 | |
|---|
| 340 | probelist->update(); |
|---|
| 341 | selected_list->update(); |
|---|
| 342 | } |
|---|
| 343 | |
|---|
| 344 | MP_Window::MP_Window(AW_root *aw_root, GBDATA *gb_main) { |
|---|
| 345 | int max_seq_col = 35; |
|---|
| 346 | int max_seq_hgt = 15; |
|---|
| 347 | |
|---|
| 348 | #if defined(DEBUG) |
|---|
| 349 | static bool initialized = false; |
|---|
| 350 | mp_assert(!initialized); // this function may only be called once! |
|---|
| 351 | initialized = true; |
|---|
| 352 | #endif |
|---|
| 353 | |
|---|
| 354 | aw_root->awar(AWAR_DEFAULT_ALIGNMENT)->add_callback(makeRootCallback(track_ali_change_cb, gb_main)); |
|---|
| 355 | track_ali_change_cb(aw_root, gb_main); |
|---|
| 356 | |
|---|
| 357 | result_window = NULp; |
|---|
| 358 | |
|---|
| 359 | aws = new AW_window_simple; |
|---|
| 360 | aws->init(aw_root, "MULTIPROBE", "MULTI_PROBE"); |
|---|
| 361 | aws->load_xfig("multiprobe.fig"); |
|---|
| 362 | |
|---|
| 363 | aws->at("close"); |
|---|
| 364 | aws->callback(MP_close_main); |
|---|
| 365 | aws->create_button("CLOSE", "CLOSE"); |
|---|
| 366 | |
|---|
| 367 | aws->at("help"); |
|---|
| 368 | aws->callback(makeHelpCallback("multiprobe.hlp")); |
|---|
| 369 | aws->create_button("HELP", "HELP"); |
|---|
| 370 | |
|---|
| 371 | aws->button_length(7); |
|---|
| 372 | aws->at("Selectedprobes"); |
|---|
| 373 | aw_root->awar(MP_AWAR_SELECTEDPROBES)->add_callback(MP_selected_chosen); |
|---|
| 374 | selected_list = aws->create_selection_list(MP_AWAR_SELECTEDPROBES, max_seq_col, max_seq_hgt); |
|---|
| 375 | |
|---|
| 376 | const StorableSelectionList *storable_selected_list = new StorableSelectionList(TypedSelectionList("prb", selected_list, "probes", "selected_probes"), mp_list2file, mp_file2list); |
|---|
| 377 | |
|---|
| 378 | selected_list->insert_default("", ""); |
|---|
| 379 | |
|---|
| 380 | aws->at("Probelist"); |
|---|
| 381 | probelist = aws->create_selection_list(MP_AWAR_PROBELIST); |
|---|
| 382 | const StorableSelectionList *storable_probelist = new StorableSelectionList(TypedSelectionList("prb", probelist, "probes", "all_probes"), mp_list2file, mp_file2list); |
|---|
| 383 | probelist->insert_default("", ""); |
|---|
| 384 | |
|---|
| 385 | aws->at("collect"); |
|---|
| 386 | awt_create_collect_buttons(aws, true, MP_collect_probes); |
|---|
| 387 | |
|---|
| 388 | aws->auto_space(5, 5); |
|---|
| 389 | aws->button_length(7); |
|---|
| 390 | |
|---|
| 391 | for (int rightSide = 0; rightSide <= 1; ++rightSide) { |
|---|
| 392 | const StorableSelectionList *storableList = rightSide ? storable_selected_list : storable_probelist; |
|---|
| 393 | const char *id_suffix = rightSide ? "SELECTED_PROBES" : "PROBES"; |
|---|
| 394 | |
|---|
| 395 | AW_selection_list *sellist = storableList->get_typedsellist().get_sellist(); |
|---|
| 396 | |
|---|
| 397 | aws->at(rightSide ? "RightButtons" : "LeftButtons"); |
|---|
| 398 | |
|---|
| 399 | aws->callback(makeCreateWindowCallback(create_load_box_for_selection_lists, storableList)); |
|---|
| 400 | aws->create_button(GBS_global_string("LOAD_%s", id_suffix), "LOAD"); |
|---|
| 401 | |
|---|
| 402 | aws->callback(makeCreateWindowCallback(create_save_box_for_selection_lists, storableList)); |
|---|
| 403 | aws->create_button(GBS_global_string("SAVE_%s", id_suffix), "SAVE"); |
|---|
| 404 | |
|---|
| 405 | aws->callback(makeWindowCallback(awt_clear_selection_list_cb, sellist)); |
|---|
| 406 | aws->create_button(GBS_global_string("CLEAR_%s", id_suffix), "CLEAR"); |
|---|
| 407 | |
|---|
| 408 | aws->callback(makeWindowCallback(MP_delete_selected, sellist)); |
|---|
| 409 | aws->create_button(GBS_global_string("DELETE_%s", id_suffix), "DELETE"); |
|---|
| 410 | } |
|---|
| 411 | |
|---|
| 412 | aws->at("Quality"); |
|---|
| 413 | aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559) |
|---|
| 414 | aws->create_option_menu(MP_AWAR_QUALITY); |
|---|
| 415 | aws->insert_option("High Priority", "", 5); |
|---|
| 416 | aws->insert_option(" 4", "", 4); |
|---|
| 417 | aws->insert_option("Normal 3", "", 3); |
|---|
| 418 | aws->insert_option(" 2", "", 2); |
|---|
| 419 | aws->insert_option("Low Prio. 1", "", 1); |
|---|
| 420 | aws->update_option_menu(); |
|---|
| 421 | |
|---|
| 422 | aws->at("add"); |
|---|
| 423 | aws->callback(MP_new_sequence); |
|---|
| 424 | aws->create_autosize_button("ADD_PROBE", "ADD"); |
|---|
| 425 | aws->at("seqin"); |
|---|
| 426 | aws->create_input_field(MP_AWAR_SEQIN, 25); |
|---|
| 427 | |
|---|
| 428 | // -------------------------------- |
|---|
| 429 | // multi probe parameters |
|---|
| 430 | |
|---|
| 431 | aws->at("PTServer"); |
|---|
| 432 | awt_create_PTSERVER_selection_button(aws, MP_AWAR_PTSERVER); |
|---|
| 433 | aw_root->awar(MP_AWAR_PTSERVER)->add_callback(MP_cache_sonden2); // remove cached probes when changing pt-server |
|---|
| 434 | |
|---|
| 435 | aws->at("NoOfProbes"); |
|---|
| 436 | aws->create_option_menu(MP_AWAR_NOOFPROBES); |
|---|
| 437 | aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559) |
|---|
| 438 | aws->insert_option("Compute 1 probe ", "", 1); |
|---|
| 439 | char str[50]; |
|---|
| 440 | for (int i=2; i<=MAXPROBECOMBIS; i++) { |
|---|
| 441 | sprintf(str, "%2d-probe-combinations", i); |
|---|
| 442 | aws->insert_option(str, "", i); |
|---|
| 443 | } |
|---|
| 444 | aws->update_option_menu(); |
|---|
| 445 | |
|---|
| 446 | aws->button_length(10); |
|---|
| 447 | aws->at("Compute"); |
|---|
| 448 | aws->callback(makeWindowCallback(MP_compute, gb_main)); |
|---|
| 449 | aws->highlight(); |
|---|
| 450 | aws->help_text("Compute possible Solutions"); |
|---|
| 451 | aws->create_button("GO", "GO"); |
|---|
| 452 | |
|---|
| 453 | aws->button_length(20); |
|---|
| 454 | aws->at("Results"); |
|---|
| 455 | aws->callback(MP_popup_result_window); |
|---|
| 456 | aws->create_button("OPEN_RESULT_WIN", "Open result window"); |
|---|
| 457 | |
|---|
| 458 | aws->at("Komplement"); |
|---|
| 459 | aws->callback(MP_cache_sonden); // @@@ used as TOGGLE_CLICK_CB (see #559) |
|---|
| 460 | aws->create_toggle(MP_AWAR_COMPLEMENT); |
|---|
| 461 | |
|---|
| 462 | aws->at("WeightedMismatches"); |
|---|
| 463 | aws->callback(MP_cache_sonden); // @@@ used as TOGGLE_CLICK_CB (see #559) |
|---|
| 464 | aws->create_toggle(MP_AWAR_WEIGHTEDMISMATCHES); |
|---|
| 465 | |
|---|
| 466 | // max non group hits |
|---|
| 467 | aws->at("Border1"); |
|---|
| 468 | aws->callback(MP_cache_sonden); // @@@ used as INPUTFIELD_CB (see #559) |
|---|
| 469 | aws->create_input_field(MP_AWAR_QUALITYBORDER1, 6); |
|---|
| 470 | |
|---|
| 471 | aws->at("OutsideMismatches"); |
|---|
| 472 | aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559) |
|---|
| 473 | aws->create_option_menu(MP_AWAR_OUTSIDEMISMATCHES); |
|---|
| 474 | aws->insert_option("3.0", "", (float)3.0); |
|---|
| 475 | aws->insert_option("2.5", "", (float)2.5); |
|---|
| 476 | aws->insert_option("2.0", "", (float)2.0); |
|---|
| 477 | aws->insert_option("1.5", "", (float)1.5); |
|---|
| 478 | aws->insert_option("1.0", "", (float)1.0); |
|---|
| 479 | aws->update_option_menu(); |
|---|
| 480 | |
|---|
| 481 | // max mismatches for group |
|---|
| 482 | aws->at("Greyzone"); |
|---|
| 483 | aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559) |
|---|
| 484 | aws->create_option_menu(MP_AWAR_GREYZONE); |
|---|
| 485 | aws->insert_default_option("0.0", "", (float)0.0); |
|---|
| 486 | for (float lauf=0.1; lauf<(float)1.0; lauf+=0.1) { |
|---|
| 487 | char strs[20]; |
|---|
| 488 | sprintf(strs, "%.1f", lauf); |
|---|
| 489 | aws->insert_option(strs, "", lauf); |
|---|
| 490 | } |
|---|
| 491 | aws->update_option_menu(); |
|---|
| 492 | |
|---|
| 493 | } |
|---|
| 494 | |
|---|
| 495 | |
|---|
| 496 | MP_Window::~MP_Window() { |
|---|
| 497 | if (result_window) result_window->hide(); |
|---|
| 498 | if (aws) aws->hide(); |
|---|
| 499 | |
|---|
| 500 | delete result_window; |
|---|
| 501 | delete aws; |
|---|
| 502 | } |
|---|
| 503 | |
|---|
| 504 | // -------------------------------------------------------------------------------- |
|---|
| 505 | |
|---|
| 506 | #ifdef UNIT_TESTS |
|---|
| 507 | #ifndef TEST_UNIT_H |
|---|
| 508 | #include <test_unit.h> |
|---|
| 509 | #endif |
|---|
| 510 | #include <command_output.h> |
|---|
| 511 | |
|---|
| 512 | inline void array2cpa(const char **content, int count, ConstStrArray& array) { |
|---|
| 513 | array.erase(); |
|---|
| 514 | for (int i = 0; i<count; ++i) { |
|---|
| 515 | array.put(content[i]); |
|---|
| 516 | } |
|---|
| 517 | } |
|---|
| 518 | |
|---|
| 519 | inline char *array2string(const CharPtrArray& array) { |
|---|
| 520 | GBS_strstruct out(1000); |
|---|
| 521 | |
|---|
| 522 | for (size_t i = 0; i<array.size(); ++i) { |
|---|
| 523 | out.cat(array[i]); |
|---|
| 524 | out.put('\n'); |
|---|
| 525 | } |
|---|
| 526 | |
|---|
| 527 | return out.release(); |
|---|
| 528 | } |
|---|
| 529 | |
|---|
| 530 | static arb_test::match_expectation inputConvertsInto(const char *input, const char *expected_result) { |
|---|
| 531 | ConstStrArray lines; |
|---|
| 532 | GBT_split_string(lines, input, "\n", SPLIT_DROPEMPTY); |
|---|
| 533 | |
|---|
| 534 | using namespace arb_test; |
|---|
| 535 | expectation_group expected; |
|---|
| 536 | |
|---|
| 537 | StrArray display, value; |
|---|
| 538 | expected.add(doesnt_report_error(mp_file2list(lines, display, value))); |
|---|
| 539 | |
|---|
| 540 | char *displ_as_string = array2string(display); |
|---|
| 541 | char *value_as_string = array2string(value); |
|---|
| 542 | |
|---|
| 543 | expected.add(that(displ_as_string).is_equal_to(expected_result)); |
|---|
| 544 | expected.add(that(value_as_string).is_equal_to(expected_result)); |
|---|
| 545 | |
|---|
| 546 | free(value_as_string); |
|---|
| 547 | free(displ_as_string); |
|---|
| 548 | |
|---|
| 549 | return all().ofgroup(expected); |
|---|
| 550 | } |
|---|
| 551 | |
|---|
| 552 | #define TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(input,expected) TEST_EXPECTATION(inputConvertsInto(input, expected)) |
|---|
| 553 | #define TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS__BROKEN(input,expected) TEST_EXPECTATION__BROKEN(inputConvertsInto(input, expected)) |
|---|
| 554 | |
|---|
| 555 | void TEST_load_probe_design_results() { |
|---|
| 556 | { |
|---|
| 557 | const char *expected = |
|---|
| 558 | "3#0# 521#GCAGCCGCGGUAAUACGG\n" |
|---|
| 559 | "3#0# 510#ACUCCGUGCCAGCAGCCG\n" |
|---|
| 560 | "3#0# 511#CUCCGUGCCAGCAGCCGC\n" |
|---|
| 561 | "3#0# 512#UCCGUGCCAGCAGCCGCG\n" |
|---|
| 562 | "3#0# 513#CCGUGCCAGCAGCCGCGG\n" |
|---|
| 563 | "3#0# 509#AACUCCGUGCCAGCAGCC\n"; |
|---|
| 564 | |
|---|
| 565 | const char *old_probeDesignSave = |
|---|
| 566 | "Probe design Parameters:\n" |
|---|
| 567 | "Length of probe 18\n" |
|---|
| 568 | "Temperature [30.0 -100.0]\n" |
|---|
| 569 | "GC-Content [50.0 -100.0]\n" |
|---|
| 570 | "E.Coli Position [any]\n" |
|---|
| 571 | "Max Non Group Hits 0\n" |
|---|
| 572 | "Min Group Hits 50%\n" |
|---|
| 573 | "Target le apos ecol grps G+C 4GC+2AT Probe sequence | Decrease T by n*.3C -> probe matches n non group species\n" |
|---|
| 574 | "GCAGCCGCGGUAAUACGG 18 A= 4398 521 23 66.7 60.0 CCGUAUUACCGCGGCUGC | 0; 0; 0; 0; 0; 0; 0; 0; 35; 35; 35; 38; 74; 74; 74; 77;113;113;113;148;\n" |
|---|
| 575 | "ACUCCGUGCCAGCAGCCG 18 B= 3852 510 23 72.2 62.0 CGGCUGCUGGCACGGAGU | 0; 0; 0; 0; 0; 40; 40; 40; 80; 80; 80; 80;120;120;120;200;200;200;200;201;\n" |
|---|
| 576 | "CUCCGUGCCAGCAGCCGC 18 B+ 4 511 23 77.8 64.0 GCGGCUGCUGGCACGGAG | 0; 0; 0; 0; 0; 40; 40; 40; 40; 80; 80; 80;160;160;160;160;201;201;201;201;\n" |
|---|
| 577 | "UCCGUGCCAGCAGCCGCG 18 B+ 7 512 23 77.8 64.0 CGCGGCUGCUGGCACGGA | 0; 0; 0; 0; 0; 40; 40; 40;120;120;120;120;160;160;161;201;201;201;202;202;\n" |
|---|
| 578 | "CCGUGCCAGCAGCCGCGG 18 B+ 9 513 23 83.3 66.0 CCGCGGCUGCUGGCACGG | 0; 0; 0; 0; 0; 80; 80; 80; 80;120;120;121;161;161;161;162;203;203;204;204;\n" |
|---|
| 579 | "AACUCCGUGCCAGCAGCC 18 B- 1 509 22 66.7 60.0 GGCUGCUGGCACGGAGUU | 0; 0; 0; 0; 0; 40; 40; 40; 80; 80; 80;120;120;120;120;160;160;160;240;240;\n"; |
|---|
| 580 | |
|---|
| 581 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(old_probeDesignSave, expected); |
|---|
| 582 | |
|---|
| 583 | |
|---|
| 584 | const char *old_multiprobeInputSave = // old multi-probe saved probe (i.e. not target) sequences -> load shall correct that |
|---|
| 585 | "3,0# 521#CCGUAUUACCGCGGCUGC\n" |
|---|
| 586 | "3,0# 510#CGGCUGCUGGCACGGAGU\n" |
|---|
| 587 | "3,0# 511#GCGGCUGCUGGCACGGAG\n" |
|---|
| 588 | "3,0# 512#CGCGGCUGCUGGCACGGA\n" |
|---|
| 589 | "3,0# 513#CCGCGGCUGCUGGCACGG\n" |
|---|
| 590 | "3,0# 509#GGCUGCUGGCACGGAGUU\n"; |
|---|
| 591 | |
|---|
| 592 | { |
|---|
| 593 | LocallyModify<char> TorU(T_or_U_for_load, 'U'); |
|---|
| 594 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(old_multiprobeInputSave, expected); |
|---|
| 595 | } |
|---|
| 596 | |
|---|
| 597 | const char *new_probeDesignSave_v1 = |
|---|
| 598 | "Probe design Parameters:,\n" |
|---|
| 599 | "Length of probe 18,\n" |
|---|
| 600 | "Temperature [30.0 -100.0],\n" |
|---|
| 601 | "GC-Content [50.0 -100.0],\n" |
|---|
| 602 | "E.Coli Position [any],\n" |
|---|
| 603 | "Max Non Group Hits 0,\n" |
|---|
| 604 | "Min Group Hits 50%,\n" |
|---|
| 605 | "Target le apos ecol grps G+C 4GC+2AT Probe sequence | Decrease T by n*.3C -> probe matches n non group species,\n" |
|---|
| 606 | "GCAGCCGCGGUAAUACGG 18 A= 4398 521 23 66.7 60.0 CCGUAUUACCGCGGCUGC | 0; 0; 0; 0; 0; 0; 0; 0; 35; 35; 35; 38; 74; 74; 74; 77;113;113;113;148;,GCAGCCGCGGUAAUACGG\n" |
|---|
| 607 | "ACUCCGUGCCAGCAGCCG 18 B= 3852 510 23 72.2 62.0 CGGCUGCUGGCACGGAGU | 0; 0; 0; 0; 0; 40; 40; 40; 80; 80; 80; 80;120;120;120;200;200;200;200;201;,ACUCCGUGCCAGCAGCCG\n" |
|---|
| 608 | "CUCCGUGCCAGCAGCCGC 18 B+ 4 511 23 77.8 64.0 GCGGCUGCUGGCACGGAG | 0; 0; 0; 0; 0; 40; 40; 40; 40; 80; 80; 80;160;160;160;160;201;201;201;201;,CUCCGUGCCAGCAGCCGC\n" |
|---|
| 609 | "UCCGUGCCAGCAGCCGCG 18 B+ 7 512 23 77.8 64.0 CGCGGCUGCUGGCACGGA | 0; 0; 0; 0; 0; 40; 40; 40;120;120;120;120;160;160;161;201;201;201;202;202;,UCCGUGCCAGCAGCCGCG\n" |
|---|
| 610 | "CCGUGCCAGCAGCCGCGG 18 B+ 9 513 23 83.3 66.0 CCGCGGCUGCUGGCACGG | 0; 0; 0; 0; 0; 80; 80; 80; 80;120;120;121;161;161;161;162;203;203;204;204;,CCGUGCCAGCAGCCGCGG\n" |
|---|
| 611 | "AACUCCGUGCCAGCAGCC 18 B- 1 509 22 66.7 60.0 GGCUGCUGGCACGGAGUU | 0; 0; 0; 0; 0; 40; 40; 40; 80; 80; 80;120;120;120;120;160;160;160;240;240;,AACUCCGUGCCAGCAGCC\n"; |
|---|
| 612 | |
|---|
| 613 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(new_probeDesignSave_v1, expected); |
|---|
| 614 | |
|---|
| 615 | |
|---|
| 616 | const char *new_multiprobeInputSave = |
|---|
| 617 | "3#0# 521#GCAGCCGCGGUAAUACGG\n" |
|---|
| 618 | "3#0# 510#ACUCCGUGCCAGCAGCCG\n" |
|---|
| 619 | "3#0# 511#CUCCGUGCCAGCAGCCGC\n" |
|---|
| 620 | "3#0# 512#UCCGUGCCAGCAGCCGCG\n" |
|---|
| 621 | "3#0# 513#CCGUGCCAGCAGCCGCGG\n" |
|---|
| 622 | "3#0# 509#AACUCCGUGCCAGCAGCC\n"; |
|---|
| 623 | |
|---|
| 624 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(new_multiprobeInputSave, expected); |
|---|
| 625 | } |
|---|
| 626 | } |
|---|
| 627 | |
|---|
| 628 | static const char *recent_expected = |
|---|
| 629 | "3#0# 82#CGAAAGGAAGAUUA\n" |
|---|
| 630 | "3#0# 82#CGAAAGGAAGAUUAA\n" |
|---|
| 631 | "3#0# 86#AGGAAGAUUAAUACC\n" |
|---|
| 632 | "3#0# 87#GGAAGAUUAAUACC\n" |
|---|
| 633 | "3#0# 21#GUCGAGCGAUGAAG\n" |
|---|
| 634 | "3#0# 20#AGUCGAGCGAUGAAG\n" |
|---|
| 635 | "3#0# 20#AGUCGAGCGAUGAA\n" |
|---|
| 636 | "3#0# 19#AAGUCGAGCGAUGAA\n" |
|---|
| 637 | "3#0# 18#CAAGUCGAGCGAUGA\n" |
|---|
| 638 | "3#0# 19#AAGUCGAGCGAUGA\n" |
|---|
| 639 | "3#0# 17#UCAAGUCGAGCGAUG\n" |
|---|
| 640 | "3#0# 18#CAAGUCGAGCGAUG\n" |
|---|
| 641 | "3#0# 16#AUCAAGUCGAGCGAU\n" |
|---|
| 642 | "3#0# 17#UCAAGUCGAGCGAU\n" |
|---|
| 643 | "3#0# 16#AUCAAGUCGAGCGA\n"; |
|---|
| 644 | |
|---|
| 645 | static const char *recent_probeDesignSave = |
|---|
| 646 | "Probe design parameters:,\n" |
|---|
| 647 | "Length of probe 14-15,\n" |
|---|
| 648 | "Temperature [ 0.0 -400.0],\n" |
|---|
| 649 | "GC-content [30.0 - 80.0],\n" |
|---|
| 650 | "E.Coli position [any],\n" |
|---|
| 651 | "Max. nongroup hits 0,\n" |
|---|
| 652 | "Min. group hits 100% (max. rejected coverage: 75%),\n" |
|---|
| 653 | "Target le apos ecol qual grps G+C temp Probe sequence | Decrease T by n*.3C -> probe matches n non group species,\n" |
|---|
| 654 | "CGAAAGGAAGAUUA 14 A=94 82 77 4 35.7 38.0 UAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -,CGAAAGGAAGAUUA\n" |
|---|
| 655 | "CGAAAGGAAGAUUAA 15 A+ 0 82 77 4 33.3 40.0 UUAAUCUUCCUUUCG | - - - - - - - - - - - - - - - - - - - -,CGAAAGGAAGAUUAA\n" |
|---|
| 656 | "AGGAAGAUUAAUACC 15 A+ 4 86 77 4 33.3 40.0 GGUAUUAAUCUUCCU | - - - - - - - - - - - - - - - - - - - -,AGGAAGAUUAAUACC\n" |
|---|
| 657 | "GGAAGAUUAAUACC 14 A+ 5 87 77 4 35.7 38.0 GGUAUUAAUCUUCC | - - - - - - - - - - - - - - - - - - - -,GGAAGAUUAAUACC\n" |
|---|
| 658 | "GUCGAGCGAUGAAG 14 B=22 21 77 4 57.1 44.0 CUUCAUCGCUCGAC | - - - - - - - - - - - - - - - - - - - 2,GUCGAGCGAUGAAG\n" |
|---|
| 659 | "AGUCGAGCGAUGAAG 15 B- 1 20 73 4 53.3 46.0 CUUCAUCGCUCGACU | - - - - - - - - - - - - - - - - - - 2 2,AGUCGAGCGAUGAAG\n" |
|---|
| 660 | "AGUCGAGCGAUGAA 14 B- 1 20 57 4 50.0 42.0 UUCAUCGCUCGACU | - - - - - - - - - - - - - - 2 2 2 2 2 2,AGUCGAGCGAUGAA\n" |
|---|
| 661 | "AAGUCGAGCGAUGAA 15 B- 2 19 53 4 46.7 44.0 UUCAUCGCUCGACUU | - - - - - - - - - - - - - 2 2 2 2 2 2 2,AAGUCGAGCGAUGAA\n" |
|---|
| 662 | "CAAGUCGAGCGAUGA 15 B- 3 18 41 4 53.3 46.0 UCAUCGCUCGACUUG | - - - - - - - - - - 2 2 2 2 2 2 2 2 2 2,CAAGUCGAGCGAUGA\n" |
|---|
| 663 | "AAGUCGAGCGAUGA 14 B- 2 19 41 4 50.0 42.0 UCAUCGCUCGACUU | - - - - - - - - - - 2 2 2 2 2 2 2 2 2 2,AAGUCGAGCGAUGA\n" |
|---|
| 664 | "UCAAGUCGAGCGAUG 15 B- 4 17 25 4 53.3 46.0 CAUCGCUCGACUUGA | - - - - - - 2 2 2 2 2 2 2 2 2 2 2 2 9 9,UCAAGUCGAGCGAUG\n" |
|---|
| 665 | "CAAGUCGAGCGAUG 14 B- 3 18 25 4 57.1 44.0 CAUCGCUCGACUUG | - - - - - - 2 2 2 2 2 2 2 2 2 2 2 2 2 2,CAAGUCGAGCGAUG\n" |
|---|
| 666 | "AUCAAGUCGAGCGAU 15 B- 5 16 5 4 46.7 44.0 AUCGCUCGACUUGAU | - 2 2 2 2 2 2 2 9 9 9 9 9 9 9 9 9 9 9 9,AUCAAGUCGAGCGAU\n" |
|---|
| 667 | "UCAAGUCGAGCGAU 14 B- 4 17 5 4 50.0 42.0 AUCGCUCGACUUGA | - 2 2 2 2 2 2 2 2 9 9 9 9 9 9 9 9 9 9 9,UCAAGUCGAGCGAU\n" |
|---|
| 668 | "AUCAAGUCGAGCGA 14 B- 5 16 5 4 50.0 42.0 UCGCUCGACUUGAU | - 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9,AUCAAGUCGAGCGA"; |
|---|
| 669 | |
|---|
| 670 | void TEST_AFTER_SLOW_recent_probe_design_result() { |
|---|
| 671 | // -------------------------------------------------------------------------------- |
|---|
| 672 | // whenever probe design output changes, copy current 'recent_probeDesignSave' and |
|---|
| 673 | // 'recent_expected' into TEST_load_probe_design_results, to ensure ARB can load |
|---|
| 674 | // any saved probe design ever created with ARB. |
|---|
| 675 | |
|---|
| 676 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(recent_probeDesignSave, recent_expected); |
|---|
| 677 | } |
|---|
| 678 | |
|---|
| 679 | void TEST_SLOW_design_probes_and_load_result() { |
|---|
| 680 | TEST_SETUP_GLOBAL_ENVIRONMENT("ptserver"); |
|---|
| 681 | |
|---|
| 682 | CommandOutput designed_probes("arb_probe serverid=-666 designprobelength=14 designmaxprobelength=15 designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr designmintargets=100", true); |
|---|
| 683 | TEST_EXPECT_NO_ERROR(designed_probes.get_error()); |
|---|
| 684 | |
|---|
| 685 | // Simulate result of designing probes in ARB_NT and saving the result to a file: |
|---|
| 686 | char *saved_design_result = NULp; // content of that file |
|---|
| 687 | { |
|---|
| 688 | ConstStrArray lines; |
|---|
| 689 | GBT_split_string(lines, designed_probes.get_stdoutput(), "\n", SPLIT_DROPEMPTY); |
|---|
| 690 | |
|---|
| 691 | StrArray saved_lines; |
|---|
| 692 | |
|---|
| 693 | for (size_t i = 0; i<lines.size(); ++i) { |
|---|
| 694 | char *probe; // same as awar-value of probe-design-resultlist in ARB_NT |
|---|
| 695 | { |
|---|
| 696 | size_t plen = strspn(lines[i], "acgtuACGTU"); |
|---|
| 697 | if (plen<10) { // no probe at start // @@@ 10 is min. probelen, use a global definition here! |
|---|
| 698 | probe = ARB_strdup(""); |
|---|
| 699 | } |
|---|
| 700 | else { |
|---|
| 701 | probe = ARB_strndup(lines[i], plen); |
|---|
| 702 | } |
|---|
| 703 | } |
|---|
| 704 | |
|---|
| 705 | char *conv4save = GBS_string_eval(lines[i], ":,=;"); // saving selection list converts comma to semicolon |
|---|
| 706 | arb_assert(conv4save); |
|---|
| 707 | |
|---|
| 708 | saved_lines.put(GBS_global_string_copy("%s,%s", conv4save, probe)); |
|---|
| 709 | |
|---|
| 710 | free(conv4save); |
|---|
| 711 | free(probe); |
|---|
| 712 | } |
|---|
| 713 | |
|---|
| 714 | saved_design_result = GBT_join_strings(saved_lines, '\n'); |
|---|
| 715 | TEST_EXPECT_EQUAL(saved_design_result, recent_probeDesignSave); // see comment in TEST_AFTER_SLOW_recent_probe_design_result |
|---|
| 716 | } |
|---|
| 717 | |
|---|
| 718 | TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(saved_design_result, recent_expected); |
|---|
| 719 | free(saved_design_result); |
|---|
| 720 | } |
|---|
| 721 | |
|---|
| 722 | |
|---|
| 723 | #endif // UNIT_TESTS |
|---|
| 724 | |
|---|
| 725 | // -------------------------------------------------------------------------------- |
|---|