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