source: branches/ali/MULTI_PROBE/MP_Window.cxx

Last change on this file was 19366, checked in by westram, 23 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.3 KB
RevLine 
[6421]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
[6490]11#include "MP_externs.hxx"
12#include "MultiProbe.hxx"
13#include "mp_proto.hxx"
[6421]14
[6490]15#include <awt_sel_boxes.hxx>
[8771]16#include <awt_modules.hxx>
[6421]17#include <aw_select.hxx>
[6422]18#include <aw_file.hxx>
[6867]19#include <aw_msg.hxx>
20#include <aw_root.hxx>
[7916]21#include <aw_awar_defs.hxx>
[6422]22
[8762]23#include <arb_strarray.h>
24#include <arb_defs.h>
25#include <arb_strbuf.h>
26#include <arbdbt.h>
[11023]27#include <ad_cb.h>
[8762]28#include <RegExpr.hxx>
29
[6490]30// **************************************************************************
[2]31
[8729]32AW_selection_list *selected_list;
[2]33AW_selection_list *result_probes_list;
34
[17396]35static AW_selection_list *probelist;
[2]36
[17396]37
[8771]38AW_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");
[2]43
[8771]44        result_window->auto_space(5, 5);
[18730]45
[8771]46        result_window->button_length(7);
47        result_window->at("close");
48        result_window->callback(AW_POPDOWN);
49        result_window->create_button("CLOSE", "CLOSE");
[2]50
[8771]51        result_window->at("Help");
[10863]52        result_window->callback(makeHelpCallback("multiproberesults.hlp"));
[8771]53        result_window->create_button("HELP", "HELP");
[2]54
[8771]55        result_window->at("Comment");
[16763]56        result_window->callback(makeWindowCallback(MP_Comment, (const char *)NULp));
[8771]57        result_window->create_input_field(MP_AWAR_RESULTPROBESCOMMENT);
[2]58
[8771]59        result_window->at("box");
[14730]60        aw_root->awar(MP_AWAR_RESULTPROBES)->add_callback(MP_result_combination_chosen);
[18964]61        result_probes_list = result_window->create_selection_list(MP_AWAR_RESULTPROBES);
[8771]62        result_probes_list->set_file_suffix("mpr");
63        result_probes_list->insert_default("", "");
[962]64
[8771]65        const StorableSelectionList *storable_probes_list = new StorableSelectionList(TypedSelectionList("mpr", result_probes_list, "multiprobes", "multi_probes"));
[962]66
[8771]67        result_window->at("buttons");
[12085]68        result_window->callback(makeCreateWindowCallback(create_load_box_for_selection_lists, storable_probes_list));
[8771]69        result_window->create_button("LOAD_RPL", "LOAD");
[962]70
[12085]71        result_window->callback(makeCreateWindowCallback(create_save_box_for_selection_lists, storable_probes_list));
[8771]72        result_window->create_button("SAVE_RPL", "SAVE");
[8762]73
[12085]74        result_window->callback(makeWindowCallback(awt_clear_selection_list_cb, result_probes_list));
[8771]75        result_window->create_button("CLEAR", "CLEAR");
[2]76
[12169]77        result_window->callback(makeWindowCallback(MP_delete_selected, result_probes_list));
[8771]78        result_window->create_button("DELETE", "DELETE");
[2]79
[8771]80        // change comment :
[962]81
[8771]82        result_window->button_length(8);
[962]83
[8771]84        result_window->at("comment");
[14452]85        result_window->callback(makeWindowCallback(MP_Comment, "Bad"));
[8771]86        result_window->create_button("MARK_AS_BAD", "BAD");
[962]87
[14452]88        result_window->callback(makeWindowCallback(MP_Comment, "???"));
[8771]89        result_window->create_button("MARK_AS_GOOD", "???");
[962]90
[14452]91        result_window->callback(makeWindowCallback(MP_Comment, "Good"));
[8771]92        result_window->create_button("MARK_AS_BEST", "Good");
[962]93
[8771]94        result_window->at("auto");
95        result_window->create_toggle(MP_AWAR_AUTOADVANCE);
[962]96
[8771]97        // tree actions :
[2]98
[8771]99        result_window->button_length(3);
[962]100
[8771]101        result_window->at("ct_back");
[14452]102        result_window->callback(makeWindowCallback(MP_show_probes_in_tree_move, true, result_probes_list));
[9777]103        result_window->create_button("COLOR_TREE_BACKWARD", "#rightleft_small.xpm");
[962]104
[8771]105        result_window->at("ct_fwd");
[14452]106        result_window->callback(makeWindowCallback(MP_show_probes_in_tree_move, false, result_probes_list));
[9777]107        result_window->create_button("COLOR_TREE_FORWARD", "#leftright_small.xpm");
[962]108
[8771]109        result_window->button_length(8);
[962]110
[8771]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");
[962]115
[8771]116        result_window->at("MarkTree");
117        result_window->callback(MP_mark_probes_in_tree);
118        result_window->create_button("MARK_TREE", "GO");
[962]119
[8771]120        result_window->at("GroupAll");
121        result_window->callback(MP_group_all_except_marked);
122        result_window->create_button("GROUP_UNMARKED", "GO");
[962]123
[8771]124        result_window->at("StandardColor");
125        result_window->callback(MP_normal_colors_in_tree);
126        result_window->create_button("RESET_COLORS", "GO");
127    }
[2]128    return result_window;
129}
130
[8762]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:
[18730]138//
[8762]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'
[6385]146
[962]147
[8762]148#define SPACED(expr) "[[:space:]]*" expr "[[:space:]]*"
[962]149
[8762]150inline 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);
[2]152}
153
[8762]154static GB_ERROR mp_list2file(const CharPtrArray& display, const CharPtrArray& value, StrArray& line) {
[16763]155    GB_ERROR error = NULp;
[962]156
[8762]157    if (value.empty()) error = "nothing to save";
[2]158
[8762]159    for (size_t i = 0; i<display.size() && !error; ++i) {
[15176]160        line.put(ARB_strdup(display[i]));
[3008]161    }
[2]162
[8762]163    return error;
[3008]164}
[2]165
[8762]166static char T_or_U_for_load = 0;
[2]167
[8762]168static GB_ERROR mp_file2list(const CharPtrArray& line, StrArray& display, StrArray& value) {
[16763]169    GB_ERROR error = NULp;
[6385]170
[8762]171    if (line.empty()) error = "empty file";
[962]172
[8762]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;
[2]178
[8762]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;
[15587]183                if (reg_saved.has_failed()) aw_message(reg_saved.get_error());
[3008]184            }
185            else {
[12138]186                char T_or_U = T_or_U_for_load ? T_or_U_for_load : 'U';
187
[8762]188                std::string sep = reg_saved.subexpr_match(2)->extract(line[i]);
[3008]189
[8762]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());
[3008]193
[8762]194                std::string probe = reg_saved.subexpr_match(5)->extract(line[i]);
[962]195
[8762]196                if (sep[0] == ',') { // old format (saved probe instead of probe-target)
197                    size_t  plen   = probe.length();
[15176]198                    char   *dprobe = ARB_strndup(probe.c_str(), plen);
[962]199
[12138]200                    GBT_reverseComplementNucSequence(dprobe, plen, T_or_U);
[8762]201                    probe = dprobe;
202                    free(dprobe);
[979]203                }
[8762]204
205                char *entry = gen_display(quality, singlemis, ecoli, probe.c_str());
206                display.put(entry); // transfers ownership - dont free!
[15176]207                value.put(ARB_strdup(entry));
[979]208            }
[1606]209        }
[2]210
[8762]211        if (!isSavedFormat) {
212            // delete attempt to read saved format:
213            display.clear();
214            value.clear();
[962]215
[11060]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);
[2]226
[8762]227            for (size_t i = 0; i<line.size() && !error; ++i) {
[16763]228                char *probe       = NULp;
229                char *description = NULp;
[8762]230                bool  new_format  = false;
[3008]231
[8762]232                const char *comma = strchr(line[i], ',');
233                if (comma) {
[15176]234                    description = ARB_strpartdup(line[i], comma-1);
[5982]235
[8762]236                    const char *cprobe = comma+1;
237                    while (cprobe[0] == ' ') ++cprobe;
[15176]238                    probe = ARB_strdup(cprobe);
[18730]239
[8762]240                    new_format = true;
241                }
242                else {
[15176]243                    description = ARB_strdup(line[i]);
[8762]244                }
[962]245
[8762]246                const RegMatch *match = reg_designed.match(description);
247                if (match) { // line from probe design (old + new format)
248                    mp_assert(match->didMatch());
[2]249
[8762]250                    match = reg_designed.subexpr_match(1);
251                    mp_assert(match->didMatch());
252                    std::string parsed_probe = match->extract(description);
[2]253
[8762]254                    if (new_format) { // already got probe value -> compare
255                        if (strcmp(probe, parsed_probe.c_str()) != 0) {
[9455]256                            error = GBS_global_string("probe string mismatch (probe='%s', parsed_probe='%s', parsed from='%s')",
257                                                      probe, parsed_probe.c_str(), line[i]);
[8762]258                        }
259                    }
260                    else {
[15176]261                        probe = ARB_strdup(parsed_probe.c_str());
[8762]262                    }
[962]263
[8762]264                    if (!error) {
265                        int quality, ecoli;
[18730]266
[8762]267                        match   = reg_designed.subexpr_match(2);
268                        mp_assert(match->didMatch());
269                        ecoli   = atoi(match->extract(description).c_str());
270                        quality = 3;
[5982]271
[8762]272                        char *entry = gen_display(quality, 0, ecoli, probe);
273                        display.put(entry); // transfers ownership - dont free!
[15176]274                        value.put(ARB_strdup(entry));
[8762]275                    }
276                }
[15587]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)
[8762]283                }
[5982]284
[8762]285                free(probe);
286                free(description);
287            }
288        }
289    }
290
291    return error;
[2]292}
293
[12169]294static void track_ali_change_cb(AW_root*, GBDATA *gb_main) {
[19206]295    GB_transaction ta(gb_main);
[8762]296
[19206]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    }
[8762]307}
308
[14451]309static void MP_collect_probes(AW_window*, awt_collect_mode mode) {
[8771]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);
[15781]315                selected_list->insert(sel.get_displayed(), *sel.get_value());
[16763]316                MP_delete_selected(NULp, probelist);
[8771]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);
[15781]324                probelist->insert(sel.get_displayed(), *sel.get_value());
[16763]325                MP_delete_selected(NULp, selected_list);
[8771]326            }
327            break;
[18730]328
[8771]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
[6443]344MP_Window::MP_Window(AW_root *aw_root, GBDATA *gb_main) {
345    int max_seq_col = 35;
346    int max_seq_hgt = 15;
[2]347
[8762]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
[12138]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
[16763]357    result_window = NULp;
[962]358
[1606]359    aws = new AW_window_simple;
[8771]360    aws->init(aw_root, "MULTIPROBE", "MULTI_PROBE");
[979]361    aws->load_xfig("multiprobe.fig");
[2]362
[979]363    aws->at("close");
364    aws->callback(MP_close_main);
[6366]365    aws->create_button("CLOSE", "CLOSE");
[2]366
[979]367    aws->at("help");
[10863]368    aws->callback(makeHelpCallback("multiprobe.hlp"));
[6366]369    aws->create_button("HELP", "HELP");
[2]370
[8771]371    aws->button_length(7);
372    aws->at("Selectedprobes");
[14730]373    aw_root->awar(MP_AWAR_SELECTEDPROBES)->add_callback(MP_selected_chosen);
[18964]374    selected_list = aws->create_selection_list(MP_AWAR_SELECTEDPROBES, max_seq_col, max_seq_hgt);
[14730]375
[8771]376    const StorableSelectionList *storable_selected_list = new StorableSelectionList(TypedSelectionList("prb", selected_list, "probes", "selected_probes"), mp_list2file, mp_file2list);
[2]377
[8771]378    selected_list->insert_default("", "");
[962]379
[8771]380    aws->at("Probelist");
[18964]381    probelist = aws->create_selection_list(MP_AWAR_PROBELIST);
[8771]382    const StorableSelectionList *storable_probelist = new StorableSelectionList(TypedSelectionList("prb", probelist, "probes", "all_probes"), mp_list2file, mp_file2list);
383    probelist->insert_default("", "");
[2]384
[8771]385    aws->at("collect");
[14451]386    awt_create_collect_buttons(aws, true, MP_collect_probes);
[18730]387
[8771]388    aws->auto_space(5, 5);
389    aws->button_length(7);
[962]390
[8771]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";
[2]394
[8771]395        AW_selection_list *sellist = storableList->get_typedsellist().get_sellist();
[2]396
[8771]397        aws->at(rightSide ? "RightButtons" : "LeftButtons");
[2]398
[12085]399        aws->callback(makeCreateWindowCallback(create_load_box_for_selection_lists, storableList));
[8771]400        aws->create_button(GBS_global_string("LOAD_%s", id_suffix), "LOAD");
401
[12085]402        aws->callback(makeCreateWindowCallback(create_save_box_for_selection_lists, storableList));
[8771]403        aws->create_button(GBS_global_string("SAVE_%s", id_suffix), "SAVE");
404
[12085]405        aws->callback(makeWindowCallback(awt_clear_selection_list_cb, sellist));
[8771]406        aws->create_button(GBS_global_string("CLEAR_%s", id_suffix), "CLEAR");
407
[12169]408        aws->callback(makeWindowCallback(MP_delete_selected, sellist));
[8771]409        aws->create_button(GBS_global_string("DELETE_%s", id_suffix), "DELETE");
410    }
411
[1606]412    aws->at("Quality");
[14731]413    aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559)
[18962]414    aws->create_option_menu(MP_AWAR_QUALITY);
[6366]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);
[1606]420    aws->update_option_menu();
[2]421
[8771]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);
[962]427
[8771]428    // --------------------------------
429    //      multi probe parameters
[2]430
[8771]431    aws->at("PTServer");
[12757]432    awt_create_PTSERVER_selection_button(aws, MP_AWAR_PTSERVER);
[8771]433    aw_root->awar(MP_AWAR_PTSERVER)->add_callback(MP_cache_sonden2); // remove cached probes when changing pt-server
[2]434
[8771]435    aws->at("NoOfProbes");
[18962]436    aws->create_option_menu(MP_AWAR_NOOFPROBES);
[14731]437    aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559)
[8771]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();
[2]445
[8771]446    aws->button_length(10);
447    aws->at("Compute");
[14452]448    aws->callback(makeWindowCallback(MP_compute, gb_main));
[8771]449    aws->highlight();
450    aws->help_text("Compute possible Solutions");
451    aws->create_button("GO", "GO");
[962]452
[8771]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");
[962]457
[8771]458    aws->at("Komplement");
[14731]459    aws->callback(MP_cache_sonden); // @@@ used as TOGGLE_CLICK_CB (see #559)
[8771]460    aws->create_toggle(MP_AWAR_COMPLEMENT);
[2]461
[1606]462    aws->at("WeightedMismatches");
[14731]463    aws->callback(MP_cache_sonden); // @@@ used as TOGGLE_CLICK_CB (see #559)
[1606]464    aws->create_toggle(MP_AWAR_WEIGHTEDMISMATCHES);
[2]465
[8771]466    // max non group hits
467    aws->at("Border1");
[14741]468    aws->callback(MP_cache_sonden); // @@@ used as INPUTFIELD_CB (see #559)
[8771]469    aws->create_input_field(MP_AWAR_QUALITYBORDER1, 6);
[2]470
[8771]471    aws->at("OutsideMismatches");
[14731]472    aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559)
[18962]473    aws->create_option_menu(MP_AWAR_OUTSIDEMISMATCHES);
[8771]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
[2]482    aws->at("Greyzone");
[14731]483    aws->callback(MP_cache_sonden); // @@@ used as OPTIONMENU_SELECT_CB (see #559)
[18962]484    aws->create_option_menu(MP_AWAR_GREYZONE);
[6366]485    aws->insert_default_option("0.0", "", (float)0.0);
486    for (float lauf=0.1; lauf<(float)1.0; lauf+=0.1) {
[979]487        char strs[20];
[6366]488        sprintf(strs, "%.1f", lauf);
489        aws->insert_option(strs, "", lauf);
[2]490    }
491    aws->update_option_menu();
492
493}
494
495
[16766]496MP_Window::~MP_Window() {
[5625]497    if (result_window)  result_window->hide();
498    if (aws)            aws->hide();
[2]499
500    delete result_window;
501    delete aws;
502}
[8762]503
504// --------------------------------------------------------------------------------
505
506#ifdef UNIT_TESTS
507#ifndef TEST_UNIT_H
508#include <test_unit.h>
509#endif
[9455]510#include <command_output.h>
[8762]511
512inline 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
519inline 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
[9450]530static arb_test::match_expectation inputConvertsInto(const char *input, const char *expected_result) {
531    ConstStrArray lines;
[19366]532    GBT_split_string(lines, input, "\n", SPLIT_DROPEMPTY);
[8762]533
[9450]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
[11060]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))
[9450]554
[9455]555void TEST_load_probe_design_results() {
[11060]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";
[8762]564
[11060]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";
[8762]580
[11060]581        TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(old_probeDesignSave, expected);
[9450]582
583
[11060]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";
[9450]591
[11060]592        {
593            LocallyModify<char> TorU(T_or_U_for_load, 'U');
594            TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(old_multiprobeInputSave, expected);
595        }
[8762]596
[11060]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";
[8762]612
[11060]613        TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(new_probeDesignSave_v1, expected);
[8762]614
615
[11060]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";
[9450]623
[11060]624        TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(new_multiprobeInputSave, expected);
625    }
[8762]626}
627
[9455]628static const char *recent_expected =
629    "3#0#   82#CGAAAGGAAGAUUA\n"
[11060]630    "3#0#   82#CGAAAGGAAGAUUAA\n"
631    "3#0#   86#AGGAAGAUUAAUACC\n"
[9455]632    "3#0#   87#GGAAGAUUAAUACC\n"
633    "3#0#   21#GUCGAGCGAUGAAG\n"
[11060]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"
[9455]642    "3#0#   17#UCAAGUCGAGCGAU\n"
643    "3#0#   16#AUCAAGUCGAGCGA\n";
644
645static const char *recent_probeDesignSave =
[11060]646    "Probe design parameters:,\n"
647    "Length of probe    14-15,\n"
[9455]648    "Temperature        [ 0.0 -400.0],\n"
[11060]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";
[9455]669
670void 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
679void TEST_SLOW_design_probes_and_load_result() {
680    TEST_SETUP_GLOBAL_ENVIRONMENT("ptserver");
681
[11060]682    CommandOutput designed_probes("arb_probe serverid=-666 designprobelength=14 designmaxprobelength=15 designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr designmintargets=100", true);
[9455]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:
[16763]686    char *saved_design_result = NULp; // content of that file
[9455]687    {
688        ConstStrArray lines;
[19366]689        GBT_split_string(lines, designed_probes.get_stdoutput(), "\n", SPLIT_DROPEMPTY);
[9455]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!
[15176]698                    probe = ARB_strdup("");
[9455]699                }
700                else {
[15176]701                    probe = ARB_strndup(lines[i], plen);
[9455]702                }
703            }
704
[16374]705            char *conv4save = GBS_string_eval(lines[i], ":,=;"); // saving selection list converts comma to semicolon
[9455]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
[14225]714        saved_design_result = GBT_join_strings(saved_lines, '\n');
[19167]715        TEST_EXPECT_EQUAL(saved_design_result, recent_probeDesignSave); // see comment in TEST_AFTER_SLOW_recent_probe_design_result
[9455]716    }
717
718    TEST_EXPECT_LOADS_INTO_MULTIPROBE_AS(saved_design_result, recent_expected);
719    free(saved_design_result);
720}
721
722
[8762]723#endif // UNIT_TESTS
724
725// --------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.