source: tags/svn.1.5.4/TOOLS/arb_probe.cxx

Last change on this file was 8309, checked in by westram, 14 years ago
  • moved much code into static scope

(partly reverted by [8310])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 38.7 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : arb_probe.cxx                                     //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <PT_com.h>
12#include <arbdb.h>
13
14#include <client.h>
15#include <servercntrl.h>
16
17#include <arb_defs.h>
18#include <arb_strbuf.h>
19
20struct apd_sequence {
21    apd_sequence *next;
22    const char *sequence;
23};
24
25struct Params {
26    int         DESIGNCLIPOUTPUT;
27    int         SERVERID;
28    const char *DESIGNNAMES;
29    int         DESIGNPROBELENGTH;
30    const char *DESIGNSEQUENCE;
31
32    int         MINTEMP;
33    int         MAXTEMP;
34    int         MINGC;
35    int         MAXGC;
36    int         MAXBOND;
37    int         MINPOS;
38    int         MAXPOS;
39    int         MISHIT;
40    int         MINTARGETS;
41    const char *SEQUENCE;
42    int         MISMATCHES;
43    int         ACCEPTN;
44    int         LIMITN;
45    int         MAXRESULT;
46    int         COMPLEMENT;
47    int         WEIGHTED;
48
49    apd_sequence *sequence;
50};
51
52
53struct gl_struct {
54    aisc_com *link;
55    T_PT_LOCS locs;
56    T_PT_MAIN com;
57    int pd_design_id;
58};
59
60static Params    P;
61static gl_struct pd_gl;
62
63static int init_local_com_struct()
64{
65    const char *user = GB_getenvUSER();
66
67    if (aisc_create(pd_gl.link, PT_MAIN, pd_gl.com,
68                    MAIN_LOCS, PT_LOCS, &pd_gl.locs,
69                    LOCS_USER, user,
70                    NULL)) {
71        return 1;
72    }
73    return 0;
74}
75
76static void aw_message(const char *error) {
77    printf("%s\n", error);
78}
79
80static const char *AP_probe_pt_look_for_server(ARB_ERROR& error) {
81    const char *server_tag = GBS_ptserver_tag(P.SERVERID);
82
83    error = arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag);
84    if (error) return NULL;
85   
86    return GBS_read_arb_tcp(server_tag);
87}
88
89static char *AP_probe_design_event(ARB_ERROR& error) {
90    T_PT_PDC     pdc;
91    T_PT_TPROBE  tprobe;
92    bytestring   bs;
93    char        *match_info;
94
95    {
96        const char *servername = AP_probe_pt_look_for_server(error);
97        if (!servername) return NULL;
98
99        pd_gl.link = aisc_open(servername, &pd_gl.com, AISC_MAGIC_NUMBER);
100    }
101
102    if (!pd_gl.link) {
103        error = "Cannot contact PT_SERVER [1]";
104        return NULL;
105    }
106    if (init_local_com_struct()) {
107        error = "Cannot contact PT_SERVER [2]";
108        return NULL;
109    }
110
111    bs.data = (char*)(P.DESIGNNAMES);
112    bs.size = strlen(bs.data)+1;
113
114    if (aisc_create(pd_gl.link, PT_LOCS, pd_gl.locs,
115                    LOCS_PROBE_DESIGN_CONFIG, PT_PDC, &pdc,
116                    PDC_PROBELENGTH,  (long)P.DESIGNPROBELENGTH,
117                    PDC_MINTEMP,      (double)P.MINTEMP,
118                    PDC_MAXTEMP,      (double)P.MAXTEMP,
119                    PDC_MINGC,        P.MINGC/100.0,
120                    PDC_MAXGC,        P.MAXGC/100.0,
121                    PDC_MAXBOND,      (double)P.MAXBOND,
122                    PDC_MIN_ECOLIPOS, (long)P.MINPOS,
123                    PDC_MAX_ECOLIPOS, (long)P.MAXPOS,
124                    PDC_MISHIT,       (long)P.MISHIT,
125                    PDC_MINTARGETS,   P.MINTARGETS/100.0,
126                    PDC_CLIPRESULT,   (long)P.DESIGNCLIPOUTPUT,
127                    NULL))
128    {
129        error = "Connection to PT_SERVER lost (1)";
130        return NULL;
131    }
132
133    apd_sequence *s;
134    for (s = P.sequence; s; s = s->next) {
135        bytestring bs_seq;
136        T_PT_SEQUENCE pts;
137        bs_seq.data = (char*)s->sequence;
138        bs_seq.size = strlen(bs_seq.data)+1;
139        aisc_create(pd_gl.link, PT_PDC, pdc,
140                    PDC_SEQUENCE, PT_SEQUENCE, &pts,
141                    SEQUENCE_SEQUENCE, &bs_seq,
142                    NULL);
143    }
144
145    aisc_put(pd_gl.link, PT_PDC, pdc,
146             PDC_NAMES, &bs,
147             PDC_GO, 0,
148             NULL);
149
150    {
151        char *locs_error = 0;
152        if (aisc_get(pd_gl.link, PT_LOCS, pd_gl.locs,
153                     LOCS_ERROR, &locs_error,
154                     NULL)) {
155            aw_message ("Connection to PT_SERVER lost (1)");
156            return NULL;
157        }
158        if (*locs_error) {
159            aw_message(locs_error);
160        }
161        free(locs_error);
162    }
163
164    aisc_get(pd_gl.link, PT_PDC, pdc,
165             PDC_TPROBE, &tprobe,
166             NULL);
167
168
169    GBS_strstruct *outstr = GBS_stropen(1000);
170
171    if (tprobe) {
172        aisc_get(pd_gl.link, PT_TPROBE, tprobe,
173                 TPROBE_INFO_HEADER,   &match_info,
174                 NULL);
175        GBS_strcat(outstr, match_info);
176        GBS_chrcat(outstr, '\n');
177        free(match_info);
178    }
179
180
181    while (tprobe) {
182        if (aisc_get(pd_gl.link, PT_TPROBE, tprobe,
183                     TPROBE_NEXT,      &tprobe,
184                     TPROBE_INFO,      &match_info,
185                     NULL)) break;
186        GBS_strcat(outstr, match_info);
187        GBS_chrcat(outstr, '\n');
188        free(match_info);
189    }
190
191    aisc_close(pd_gl.link); pd_gl.link = 0;
192
193    return GBS_strclose(outstr);
194}
195
196static char *AP_probe_match_event(ARB_ERROR& error) {
197    T_PT_MATCHLIST  match_list;
198    char           *probe = 0;
199
200    {
201        const char *servername = AP_probe_pt_look_for_server(error);
202        if (!servername) return NULL;
203
204        pd_gl.link = aisc_open(servername, &pd_gl.com, AISC_MAGIC_NUMBER);
205    }
206
207    if (!pd_gl.link) {
208        error = "Cannot contact PT_SERVER [1]";
209        return NULL;
210    }
211    if (init_local_com_struct()) {
212        error = "Cannot contact PT_SERVER [2]";
213        return NULL;
214    }
215
216    if (aisc_nput(pd_gl.link, PT_LOCS, pd_gl.locs,
217                  LOCS_MATCH_REVERSED,       (long)P.COMPLEMENT,
218                  LOCS_MATCH_SORT_BY,        (long)P.WEIGHTED,
219                  LOCS_MATCH_COMPLEMENT,     0L,
220                  LOCS_MATCH_MAX_MISMATCHES, (long)P.MISMATCHES,
221                  LOCS_MATCH_N_ACCEPT,       (long)P.ACCEPTN,
222                  LOCS_MATCH_N_LIMIT,        (long)P.LIMITN,
223                  LOCS_MATCH_MAX_HITS,       (long)P.MAXRESULT,
224                  LOCS_SEARCHMATCH,          P.SEQUENCE,
225                  NULL)) {
226        free(probe);
227        error = "Connection to PT_SERVER lost (1)";
228        return NULL;
229    }
230
231    long match_list_cnt;
232   
233    bytestring bs;
234    bs.data = 0;
235    {
236        char *locs_error;
237        aisc_get(pd_gl.link, PT_LOCS, pd_gl.locs,
238                 LOCS_MATCH_LIST,      &match_list,
239                 LOCS_MATCH_LIST_CNT,  &match_list_cnt,
240                 LOCS_MATCH_STRING,    &bs,
241                 LOCS_ERROR,           &locs_error,
242                 NULL);
243        if (*locs_error) error = locs_error;
244        free(locs_error);
245    }
246    aisc_close(pd_gl.link);
247
248    return bs.data; // freed by caller
249}
250
251static int          pargc;
252static const char **pargv = NULL;
253static bool         showhelp;
254
255static int getInt(const char *param, int val, int min, int max, const char *description) {
256    if (showhelp) {
257        printf("    %s=%i [%i .. %i] %s\n", param, val, min, max, description);
258        return 0;
259    }
260    int   i;
261    const char *s = 0;
262
263    arb_assert(pargc >= 1);     // otherwise s stays 0
264
265    for (i=1; i<pargc; i++) {
266        s = pargv[i];
267        if (*s == '-') s++;
268        if (!strncasecmp(s, param, strlen(param))) break;
269    }
270    if (i==pargc) return val;
271    s += strlen(param);
272    if (*s != '=') return val;
273    s++;
274    val = atoi(s);
275    pargc--;        // remove parameter
276    for (; i<pargc; i++) {
277        pargv[i] = pargv[i+1];
278    }
279
280    if (val<min) val = min;
281    if (val>max) val = max;
282    return val;
283}
284
285static const char *getString(const char *param, const char *val, const char *description) {
286    if (showhelp) {
287        if (!val) val = "";
288        printf("    %s=%s   %s\n", param, val, description);
289        return 0;
290    }
291    int   i;
292    const char *s = 0;
293
294    arb_assert(pargc >= 1);     // otherwise s stays 0
295
296    for (i=1; i<pargc; i++) {
297        s = pargv[i];
298        if (*s == '-') s++;
299        if (!strncasecmp(s, param, strlen(param))) break;
300    }
301    if (i==pargc) return val;
302    s += strlen(param);
303    if (*s != '=') return val;
304    s++;
305    pargc--;        // remove parameter
306    for (; i<pargc; i++) {
307        pargv[i] = pargv[i+1];
308    }
309    return s;
310}
311
312static bool parseCommandLine(int argc, const char * const * const argv) {
313    pargc = argc;
314   
315    // copy argv (since parser will remove matched arguments)
316    free(pargv);
317    pargv = (const char **)malloc(sizeof(*pargv)*pargc);
318    for (int i=0; i<pargc; i++) pargv[i] = argv[i];
319
320    showhelp = (pargc <= 1);
321
322#ifdef UNIT_TESTS
323    const int minServerID   = TEST_GENESERVER_ID;
324#else // !UNIT_TESTS
325    const int minServerID   = 0;
326#endif
327
328    P.SERVERID = getInt("serverid", 0, minServerID, 100, "Server Id, look into $ARBHOME/lib/arb_tcp.dat");
329#ifdef UNIT_TESTS
330    if (P.SERVERID<0) { arb_assert(P.SERVERID == TEST_SERVER_ID || P.SERVERID == TEST_GENESERVER_ID); }
331#endif
332
333    P.DESIGNCLIPOUTPUT = getInt("designmaxhits", 100, 10, 10000, "Maximum Number of Probe Design Suggestions");
334    P.DESIGNNAMES      = getString("designnames", "",            "List of short names separated by '#'");
335
336    P.sequence = 0;
337    while  ((P.DESIGNSEQUENCE = getString("designsequence", 0, "Additional Sequences, will be added to the target group"))) {
338        apd_sequence *= new apd_sequence;
339        s->next          = P.sequence;
340        P.sequence       = s;
341        s->sequence      = P.DESIGNSEQUENCE;
342        P.DESIGNSEQUENCE = 0;
343    }
344    P.DESIGNPROBELENGTH = getInt("designprobelength", 18,  2,  100,     "Length of probe");
345    P.MINTEMP           = getInt("designmintemp",     0,   0,  400,     "Minimum melting temperature of probe");
346    P.MAXTEMP           = getInt("designmaxtemp",     400, 0,  400,     "Maximum melting temperature of probe");
347    P.MINGC             = getInt("designmingc",       30,  0,  100,     "Minimum gc content");
348    P.MAXGC             = getInt("designmaxgc",       80,  0,  100,     "Maximum gc content");
349    P.MAXBOND           = getInt("designmaxbond",     0,   0,  10,      "Not implemented");
350    P.MINPOS            = getInt("designminpos",      -1,  -1, INT_MAX, "Minimum ecoli position (-1=none)");
351    P.MAXPOS            = getInt("designmaxpos",      -1,  -1, INT_MAX, "Maximum ecoli position (-1=none)");
352    P.MISHIT            = getInt("designmishit",      0,   0,  10000,   "Number of allowed hits outside the selected group");
353    P.MINTARGETS        = getInt("designmintargets",  50,  0,  100,     "Minimum percentage of hits within the selected species");
354
355    P.SEQUENCE = getString("matchsequence",   "agtagtagt", "The sequence to search for");
356
357    P.MISMATCHES = getInt("matchmismatches", 0,       0, 5,       "Maximum Number of allowed mismatches");
358    P.COMPLEMENT = getInt("matchcomplement", 0,       0, 1,       "Match reversed and complemented probe");
359    P.WEIGHTED   = getInt("matchweighted",   0,       0, 1,       "Use weighted mismatches");
360    P.ACCEPTN    = getInt("matchacceptN",    1,       0, 20,      "Amount of N-matches not counted as mismatch");
361    P.LIMITN     = getInt("matchlimitN",     4,       0, 20,      "Limit for N-matches. If reached N-matches are mismatches");
362    P.MAXRESULT  = getInt("matchmaxresults", 1000000, 0, INT_MAX, "Max. number of matches reported (0=unlimited)");
363
364    if (pargc>1) {
365        printf("Unknown (or duplicate) parameter %s\n", pargv[1]);
366        return false;
367    }
368    return !showhelp;
369}
370
371// --------------------------------------------------------------------------------
372
373#ifdef UNIT_TESTS
374#ifndef TEST_UNIT_H
375#include <test_unit.h>
376#endif
377
378void TEST_BASIC_parseCommandLine() {
379    {
380        const char *args[] = { NULL, "serverid=0"};
381        TEST_ASSERT(parseCommandLine(ARRAY_ELEMS(args), args));
382
383        // test default values here
384        TEST_ASSERT_EQUAL(P.ACCEPTN, 1);
385        TEST_ASSERT_EQUAL(P.LIMITN, 4);
386        TEST_ASSERT_EQUAL(P.MISMATCHES, 0);
387        TEST_ASSERT_EQUAL(P.MAXRESULT, 1000000);
388    }
389
390    {
391        const char *args[] = {NULL, "serverid=4", "matchmismatches=2"};
392        TEST_ASSERT(parseCommandLine(ARRAY_ELEMS(args), args));
393        TEST_ASSERT_EQUAL(P.SERVERID, 4);
394        TEST_ASSERT_EQUAL(P.MISMATCHES, 2);
395        TEST_ASSERT_EQUAL(args[1], "serverid=4"); // check array args was not modified
396    }
397
398    {
399        const char *args[] = { NULL, "matchacceptN=0", "matchlimitN=5"};
400        TEST_ASSERT(parseCommandLine(ARRAY_ELEMS(args), args));
401        TEST_ASSERT_EQUAL(P.ACCEPTN, 0);
402        TEST_ASSERT_EQUAL(P.LIMITN, 5);
403    }
404
405    {
406        const char *args[] = { NULL, "matchmaxresults=100"};
407        TEST_ASSERT(parseCommandLine(ARRAY_ELEMS(args), args));
408        TEST_ASSERT_EQUAL(P.MAXRESULT, 100);
409    }
410}
411
412#endif // UNIT_TESTS
413
414// --------------------------------------------------------------------------------
415
416
417static char *execute(ARB_ERROR& error) {
418    char *answer;
419    if (*P.DESIGNNAMES || P.sequence) {
420        answer = AP_probe_design_event(error);
421    }
422    else {
423        answer = AP_probe_match_event(error);
424    }
425    return answer;
426}
427
428int ARB_main(int argc, const char *argv[]) {
429    bool ok = parseCommandLine(argc, argv);
430    if (ok) {
431        ARB_ERROR  error;
432        char      *answer = execute(error);
433
434        arb_assert(contradicted(answer, error));
435       
436        if (!answer) {
437            fprintf(stderr,
438                    "arb_probe: Failed to process your request\n"
439                    "           Reason: %s",
440                    error.deliver());
441            ok = false;
442        }
443        else {
444            fputs(answer, stdout);
445            free(answer);
446            error.expect_no_error();
447        }
448    }
449    return ok ? EXIT_SUCCESS : EXIT_FAILURE;
450}
451
452// --------------------------------------------------------------------------------
453
454#ifdef UNIT_TESTS
455#ifndef TEST_UNIT_H
456#include <test_unit.h>
457#endif
458
459static int test_setup(bool use_gene_ptserver) {
460    static bool setup[2] = { false, false };
461    if (!setup[use_gene_ptserver]) {
462        TEST_SETUP_GLOBAL_ENVIRONMENT(use_gene_ptserver ? "ptserver_gene" : "ptserver"); // first call will recreate the test pt-server
463        setup[use_gene_ptserver] = true;
464    }
465    return use_gene_ptserver ? TEST_GENESERVER_ID : TEST_SERVER_ID;
466}
467
468// ----------------------------------
469//      test probe design / match
470
471#define TEST_PART1(fake_argc,fake_argv)                                                 \
472    int       serverid = test_setup(use_gene_ptserver);                                 \
473    TEST_ASSERT_EQUAL(true, parseCommandLine(fake_argc, fake_argv));                    \
474    TEST_ASSERT((serverid == TEST_SERVER_ID)||(serverid == TEST_GENESERVER_ID));        \
475    P.SERVERID         = serverid;                                                      \
476    ARB_ERROR error;                                                                    \
477    char      *answer   = execute(error);                                               \
478    TEST_ASSERT_NO_ERROR(error.deliver())
479
480
481#define TEST_ARB_PROBE(fake_argc,fake_argv,expected) do {               \
482        TEST_PART1(fake_argc,fake_argv);                                \
483        TEST_ASSERT_EQUAL(answer, expected);                            \
484        free(answer);                                                   \
485    } while(0)
486
487#define TEST_ARB_PROBE__BROKEN(fake_argc,fake_argv,expected) do {       \
488        TEST_PART1(fake_argc,fake_argv);                                \
489        TEST_ASSERT_EQUAL__BROKEN(answer, expected);                    \
490        free(answer);                                                   \
491    } while(0)
492
493#define TEST_ARB_PROBE_FILT(fake_argc,fake_argv,filter,expected) do {   \
494        TEST_PART1(fake_argc,fake_argv);                                \
495        char  *filtered   = filter(answer);                             \
496        TEST_ASSERT_EQUAL(filtered, expected);                          \
497        free(filtered);                                                 \
498        free(answer);                                                   \
499    } while(0)
500
501typedef const char *CCP;
502
503void TEST_SLOW_match_geneprobe() {
504    bool use_gene_ptserver = true;
505    {
506        const char *arguments[] = {
507            "prgnamefake",
508            "matchsequence=NNUCNN",
509            "matchacceptN=4", 
510            "matchlimitN=5", 
511        };
512        CCP expectd = "    organism genename------- mis N_mis wmis pos gpos rev          'NNUCNN'\1"
513            "genome2\1" "  genome2  gene3             0     4  0.0   2    1 0   .........-UU==GG-UUGAUC\1"
514            "genome2\1" "  genome2  joined1           0     4  0.0   2    1 0   .........-UU==GG-UUGAUCCUG\1"
515            "genome2\1" "  genome2  gene2             0     4  0.0  10    4 0   ......GUU-GA==CU-GCCA\1"
516            "genome2\1" "  genome2  intergene_19_65   0     4  0.0  31   12 0   GGUUACUGC-AU==GG-UGUUCGCCU\1"
517            "genome1\1" "  genome1  intergene_17_65   0     4  0.0  31   14 0   GGUUACUGC-UA==GG-UGUUCGCCU\1"
518            "genome2\1" "  genome2  intergene_19_65   0     4  0.0  38   19 0   GCAUUCGGU-GU==GC-CUAAGCACU\1"
519            "genome1\1" "  genome1  intergene_17_65   0     4  0.0  38   21 0   GCUAUCGGU-GU==GC-CUAAGCCAU\1"
520            "genome1\1" "  genome1  intergene_17_65   0     4  0.0  56   39 0   AGCCAUGCG-AG==AU-AUGUA\1" "";
521       
522        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd);
523    }
524    {
525        const char *arguments[] = {
526            "prgnamefake",
527            "matchsequence=NGGUUN",
528            "matchacceptN=2", 
529            "matchlimitN=3", 
530        };
531        CCP expectd = "    organism genename------- mis N_mis wmis pos gpos rev          'NGGUUN'\1"
532            "genome1\1" "  genome1  joined1           0     2  0.0   5    2 0   ........C-U====G-AUCCUGC\1"
533            "genome2\1" "  genome2  intergene_19_65   0     2  0.0  21    2 0   ........G-A====A-CUGCAUUCG\1"
534            "genome1\1" "  genome1  intergene_17_65   0     2  0.0  21    4 0   ......CAG-A====A-CUGCUAUCG\1"
535            "genome2\1" "  genome2  gene3             0     2  0.0   5    4 0   ......UUU-C====G-AUC\1"
536            "genome2\1" "  genome2  joined1           0     2  0.0   5    4 0   ......UUU-C====G-AUCCUGCCA\1" "";
537
538        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd);
539    }
540
541    {
542        const char *arguments[] = {
543            "prgnamefake",
544            "matchsequence=UGAUCCU", // exists in data
545        };
546        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UGAUCCU'\1"
547            "genome1\1" "  genome1  gene2      0     0  0.0   9    1 0   .........-=======-GC\1"
548            "genome2\1" "  genome2  gene2      0     0  0.0   9    3 0   .......GU-=======-GCCA\1" "";
549
550        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // @@@ defect: probe exists as well in 'joined1' (of both genomes)
551    }
552    {
553        const char *arguments[] = {
554            "prgnamefake",
555            "matchsequence=GAUCCU",
556        };
557        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'GAUCCU'\1"
558            "genome2\1" "  genome2  gene2      0     0  0.0  10    4 0   ......GUU-======-GCCA\1" "";
559
560        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // @@@ defect: probe is part of above probe, but reports less hits
561    }
562    {
563        const char *arguments[] = {
564            "prgnamefake",
565            "matchsequence=UUUCGG", // exists only in genome2
566        };
567        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UUUCGG'\1"
568            "genome2\1" "  genome2  gene3      0     0  0.0   2    1 0   .........-======-UUGAUC\1"
569            "genome2\1" "  genome2  joined1    0     0  0.0   2    1 0   .........-======-UUGAUCCUG\1" "";
570
571        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // @@@ defect: also exists in genome2/gene1
572    }
573    {
574        const char *arguments[] = {
575            "prgnamefake",
576            "matchsequence=AUCCUG", 
577        };
578        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'AUCCUG'\1"
579            "genome2\1" "  genome2  gene2      0     0  0.0  11    5 0   .....GUUG-======-CCA\1" "";
580
581        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // @@@ defect: exists in 'gene2' and 'joined1' of both genomes
582    }
583    {
584        const char *arguments[] = {
585            "prgnamefake",
586            "matchsequence=UUGAUCCUGC",
587        };
588        CCP expectd = "    organism genename mis N_mis wmis pos gpos rev          'UUGAUCCUGC'\1"
589            "genome2\1" "  genome2  gene2      0     0  0.0   8    2 0   ........G-==========-CA\1"
590            "genome1\1" "  genome1  joined1    0     0  0.0   8    5 0   .....CUGG-==========-\1" "";
591
592        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd); // @@@ defect: also exists in 'genome2/joined1'
593    }
594}
595
596void TEST_SLOW_match_probe() {
597    bool use_gene_ptserver = false;
598    {
599        const char *arguments[] = {
600            "prgnamefake",
601            "matchsequence=UAUCGGAGAGUUUGA",
602        };
603        CCP expected = "    name---- fullname mis N_mis wmis pos ecoli rev          'UAUCGGAGAGUUUGA'\1"
604            "BcSSSS00\1" "  BcSSSS00            0     0  0.0   3     2 0   .......UU-===============-UCAAGUCGA\1";
605
606        TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
607    }
608
609    // ----------------------------------------------------------------------------
610    //      match with old(=default) N-mismatch-behavior (accepting 1 N-match)
611
612    {
613        const char *arguments[] = {
614            "prgnamefake",
615            "matchsequence=CANCUCCUUUC", // contains 1 N
616            NULL // matchmismatches
617        };
618
619        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
620            "BcSSSS00\1" "  BcSSSS00            0     1  0.0 176   162 0   CGGCUGGAU-==C========-U\1" ""; // only N-mismatch accepted
621
622        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
623            "BcSSSS00\1" "  BcSSSS00            0     1  0.0 176   162 0   CGGCUGGAU-==C========-U\1"
624            "PbcAcet2\1" "  PbcAcet2            0     2  0.0 176   162 0   CGGCUGGAU-==C=======N-N\1"
625            "ClfPerfr\1" "  ClfPerfr            1     1  0.0 176   162 0   AGAUUAAUA-=CC========-U\1";
626
627        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
628            "BcSSSS00\1" "  BcSSSS00            0     1  0.0 176   162 0   CGGCUGGAU-==C========-U\1"
629            "PbcAcet2\1" "  PbcAcet2            0     2  0.0 176   162 0   CGGCUGGAU-==C=======N-N\1"
630            "DlcTolu2\1" "  DlcTolu2            0     3  0.0 176   162 0   CGGCUGGAU-==C======NN-N\1"
631            "ClfPerfr\1" "  ClfPerfr            1     1  0.0 176   162 0   AGAUUAAUA-=CC========-U\1";
632
633        arguments[2] = "matchmismatches=0";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
634        arguments[2] = "matchmismatches=1";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
635        arguments[2] = "matchmismatches=2";  TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
636    }
637    {
638        const char *arguments[] = {
639            "prgnamefake",
640            "matchsequence=UCACCUCCUUUC", // contains no N
641            NULL // matchmismatches
642        };
643
644        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
645            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1"
646            "PbcAcet2\1" "  PbcAcet2            0     1  0.0 175   161 0   GCGGCUGGA-===========N-N\1";
647
648        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
649            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1"
650            "PbcAcet2\1" "  PbcAcet2            0     1  0.0 175   161 0   GCGGCUGGA-===========N-N\1"
651            "DlcTolu2\1" "  DlcTolu2            0     2  0.0 175   161 0   GCGGCUGGA-==========NN-N\1" "";
652
653        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
654            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1"
655            "PbcAcet2\1" "  PbcAcet2            0     1  0.0 175   161 0   GCGGCUGGA-===========N-N\1"
656            "DlcTolu2\1" "  DlcTolu2            0     2  0.0 175   161 0   GCGGCUGGA-==========NN-N\1"
657            "ClfPerfr\1" "  ClfPerfr            2     0  0.0 175   161 0   AAGAUUAAU-A=C=========-U\1" "";
658
659        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
660        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
661        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
662    }
663
664    // ----------------------------------------------
665    //      do not accept any N-matches as match
666
667    {
668        const char *arguments[] = {
669            "prgnamefake",
670            "matchsequence=CANCUCCUUUC", // contains 1 N
671            NULL, // matchmismatches
672            "matchacceptN=0",
673        };
674
675        CCP expectd0 = ""; // nothing matches
676
677        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
678            "BcSSSS00\1" "  BcSSSS00            0     1  0.0 176   162 0   CGGCUGGAU-==C========-U\1" "";
679 
680        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUUC'\1"
681            "BcSSSS00\1" "  BcSSSS00            0     1  0.0 176   162 0   CGGCUGGAU-==C========-U\1"
682            "PbcAcet2\1" "  PbcAcet2            0     2  0.0 176   162 0   CGGCUGGAU-==C=======N-N\1"
683            "ClfPerfr\1" "  ClfPerfr            1     1  0.0 176   162 0   AGAUUAAUA-=CC========-U\1" "";
684
685        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
686        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
687        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
688    }
689    {
690        const char *arguments[] = {
691            "prgnamefake",
692            "matchsequence=UCACCUCCUUUC", // contains no N
693            NULL, // matchmismatches
694            "matchacceptN=0",
695        };
696
697        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
698            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1" "";
699
700        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
701            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1"
702            "PbcAcet2\1" "  PbcAcet2            0     1  0.0 175   161 0   GCGGCUGGA-===========N-N\1" "";
703
704        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCACCUCCUUUC'\1"
705            "BcSSSS00\1" "  BcSSSS00            0     0  0.0 175   161 0   GCGGCUGGA-============-U\1"
706            "PbcAcet2\1" "  PbcAcet2            0     1  0.0 175   161 0   GCGGCUGGA-===========N-N\1"
707            "DlcTolu2\1" "  DlcTolu2            0     2  0.0 175   161 0   GCGGCUGGA-==========NN-N\1"
708            "ClfPerfr\1" "  ClfPerfr            2     0  0.0 175   161 0   AAGAUUAAU-A=C=========-U\1" "";
709       
710        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
711        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
712        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
713    }
714
715    // ----------------------------------
716    //      accept several N-matches
717
718    {
719        const char *arguments[] = {
720            "prgnamefake",
721            "matchsequence=CANCUCCUUNC", // contains 2 N
722            NULL, // matchmismatches
723            "matchacceptN=2",
724            "matchlimitN=4",
725        };
726
727        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
728            "BcSSSS00\1" "  BcSSSS00            0     2  0.0 176   162 0   CGGCUGGAU-==C======U=-U\1" "";
729
730        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
731            "BcSSSS00\1" "  BcSSSS00            0     2  0.0 176   162 0   CGGCUGGAU-==C======U=-U\1"
732            "DlcTolu2\1" "  DlcTolu2            0     3  0.0 176   162 0   CGGCUGGAU-==C=======N-N\1"
733            "PbcAcet2\1" "  PbcAcet2            0     3  0.0 176   162 0   CGGCUGGAU-==C======UN-N\1"
734            "ClfPerfr\1" "  ClfPerfr            1     2  0.0 176   162 0   AGAUUAAUA-=CC======U=-U\1" "";
735       
736        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCUCCUUNC'\1"
737            "BcSSSS00\1" "  BcSSSS00            0     2  0.0 176   162 0   CGGCUGGAU-==C======U=-U\1"
738            "DlcTolu2\1" "  DlcTolu2            0     3  0.0 176   162 0   CGGCUGGAU-==C=======N-N\1"
739            "PbcAcet2\1" "  PbcAcet2            0     3  0.0 176   162 0   CGGCUGGAU-==C======UN-N\1"
740            "ClfPerfr\1" "  ClfPerfr            1     2  0.0 176   162 0   AGAUUAAUA-=CC======U=-U\1" "";
741       
742        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
743        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
744        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
745    }
746
747    // --------------------------
748    //      truncate results
749
750    {
751        const char *arguments[] = {
752            "prgnamefake",
753            "matchsequence=CANCNCNNUNC", // contains 5N
754            NULL, // matchmismatches
755            "matchacceptN=5",
756            "matchlimitN=7",
757            "matchmaxresults=5",
758        };
759
760        CCP expectd0 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
761            "BcSSSS00\1" "  BcSSSS00            0     5  0.0 176   162 0   CGGCUGGAU-==C=U=CU=U=-U\1" "";
762
763        CCP expectd1 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
764            "BcSSSS00\1" "  BcSSSS00            0     5  0.0 176   162 0   CGGCUGGAU-==C=U=CU=U=-U\1"
765            "DlcTolu2\1" "  DlcTolu2            0     6  0.0 176   162 0   CGGCUGGAU-==C=U=CU==N-N\1"
766            "PbcAcet2\1" "  PbcAcet2            0     6  0.0 176   162 0   CGGCUGGAU-==C=U=CU=UN-N\1"
767            "LgtLytic\1" "  LgtLytic            1     5  0.0  31    26 0   GUCGAACGG-==G=A=AG=CU-AGCUUGCUA\1"
768            "ClfPerfr\1" "  ClfPerfr            1     5  0.0 111    99 0   CGGCUGGAU-==U=AUAA=G=-AGCGAUUGG\1"; // one hit is truncated here
769       
770        CCP expectd2 = "    name---- fullname mis N_mis wmis pos ecoli rev          'CANCNCNNUNC'\1"
771            "VbrFurni\1" "  VbrFurni            2     5  0.0  40    35 0   CGGCAGCGA-==A=AUUGAA=-CUUCGGGGG\1"
772            "HllHalod\1" "  HllHalod            2     5  0.0  45    40 0   AAACGAUGG-A=G=UUGC=U=-CAGGCGUCG\1"
773            "VblVulni\1" "  VblVulni            2     5  0.0  49    44 0   AGCACAGAG-A=A=UUGU=U=-UCGGGUGGC\1"
774            "LgtLytic\1" "  LgtLytic            2     5  0.0 101    89 0   GGGGAAACU-==AGCUAA=A=-CGCAUAAUC\1"
775            "ClfPerfr\1" "  ClfPerfr            2     5  0.0 172   158 0   AGGAAGAUU-A=UAC=CC=C=-UUUCU\1"; // many hits are truncated here
776
777        arguments[2] = "matchmismatches=0"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd0);
778        arguments[2] = "matchmismatches=1"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd1);
779        arguments[2] = "matchmismatches=2"; TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expectd2);
780    }
781}
782
783static char *extract_locations(const char *probe_design_result) {
784    const char *Target = strstr(probe_design_result, "\nTarget");
785    if (Target) {
786        const char *designed = strchr(Target+7, '\n');
787        if (designed) {
788            ++designed;
789            char *result = strdup("");
790
791            while (designed) {
792                const char *eol       = strchr(designed, '\n');
793                const char *space1    = strchr(designed, ' ');          if (!space1) break; // 1st space between probe and len
794                const char *nonspace  = space1+strspn(space1, " ");     if (!nonspace) break;
795                const char *space2    = strchr(nonspace, ' ');          if (!space2) break; // 1st space between len and "X="
796                const char *nonspace2 = space2+strspn(space2, " ");     if (!nonspace2) break;
797                const char *space3    = strchr(nonspace2, ' ');         if (!space3) break; // 1st space between "X=" and abs
798                const char *nonspace3 = space3+strspn(space3, " ");     if (!nonspace3) break;
799                const char *space4    = strchr(nonspace3, ' ');         if (!space4) break; // 1st space between abs and rest
800
801                char *abs = GB_strpartdup(nonspace3, space4-1);
802
803                freeset(result, GBS_global_string_copy("%s%c%c%s", result, space2[1], space2[2], abs));
804                free(abs);
805
806                designed = eol ? eol+1 : NULL;
807            }
808
809            return result;
810        }
811    }
812    return strdup("can't extract");
813}
814
815void TEST_SLOW_design_probe() {
816    bool use_gene_ptserver = false;
817    const char *arguments[] = {
818        "prgnamefake",
819        "designnames=ClnCorin#CltBotul#CPPParap#ClfPerfr",
820        "designmintargets=100",
821    };
822    const char *expected = 
823        "Probe design Parameters:\n"
824        "Length of probe      18\n"
825        "Temperature        [ 0.0 -400.0]\n"
826        "GC-Content         [30.0 -80.0]\n"
827        "E.Coli Position    [any]\n"
828        "Max Non Group Hits     0\n"
829        "Min Group Hits       100%\n"
830        "Target             le     apos ecol grps  G+C 4GC+2AT Probe sequence     | Decrease T by n*.3C -> probe matches n non group species\n"
831        "CGAAAGGAAGAUUAAUAC 18 A=    94   82    4 33.3 48.0    GUAUUAAUCUUCCUUUCG |  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n"
832        "GAAAGGAAGAUUAAUACC 18 A+     1   83    4 33.3 48.0    GGUAUUAAUCUUCCUUUC |  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n"
833        "UCAAGUCGAGCGAUGAAG 18 B=    18   17    4 50.0 54.0    CUUCAUCGCUCGACUUGA |  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n"
834        "AUCAAGUCGAGCGAUGAA 18 B-     1   16    4 44.4 52.0    UUCAUCGCUCGACUUGAU |  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  2,  3,\n";
835
836    TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
837
838    // ------------------------------------------------------
839    //      design MANY probes to test location specifier
840
841    {
842        char *positions = extract_locations(expected);
843        TEST_ASSERT_EQUAL(positions, "A=94A+1B=18B-1");
844        free(positions);
845    }
846
847    const char *arguments_loc[] = {
848        "prgnamefake",
849        // "designnames=Stsssola#Stsssola", // @@@ crashes the ptserver
850        "designnames=CPPParap#PsAAAA00",
851        "designmintargets=50", // hit at least 1 of the 2 targets
852        "designmingc=0", "designmaxgc=100", // allow all GCs
853        "designmishit=99999",  // allow enough outgroup hits
854        "designmaxhits=99999", // do not limit results
855        "designprobelength=3",
856    };
857
858    const char *expected_loc = 
859        "A=96B=141C=20D=107B+1E=110F=84G=9H=150I=145C+1D+1J=17K=122L=72C-1M=33N=114E+1O=163"
860        "P=24E+2F+1Q=138R=54O+1S=49A-1T=87G+1J-1N-1U=79F+2U-1V=129I+2H-2C+2W=12D-1D+2C-2R+1"
861        "P-1J-2O+2V-2X=92W+2W+1Y=125Z=176D-2H+1a=104H-1L+1";
862
863    TEST_ARB_PROBE_FILT(ARRAY_ELEMS(arguments_loc), arguments_loc, extract_locations, expected_loc);
864}
865
866void TEST_SLOW_match_designed_probe() {
867    bool use_gene_ptserver = false;
868    const char *arguments[] = {
869        "prgnamefake", 
870        "matchsequence=UCAAGUCGAGCGAUGAAG", 
871    };
872    CCP expected = "    name---- fullname mis N_mis wmis pos ecoli rev          'UCAAGUCGAGCGAUGAAG'\1"
873        "ClnCorin\1" "  ClnCorin            0     0  0.0  18    17 0   .GAGUUUGA-==================-UUCCUUCGG\1"
874        "CltBotul\1" "  CltBotul            0     0  0.0  18    17 0   ........A-==================-CUUCUUCGG\1"
875        "CPPParap\1" "  CPPParap            0     0  0.0  18    17 0   AGAGUUUGA-==================-UUCCUUCGG\1"
876        "ClfPerfr\1" "  ClfPerfr            0     0  0.0  18    17 0   AGAGUUUGA-==================-UUUCCUUCG\1";
877
878    TEST_ARB_PROBE(ARRAY_ELEMS(arguments), arguments, expected);
879}
880
881void TEST_SLOW_variable_defaults_in_server() {
882    test_setup(false);
883
884    const char *server_tag = GBS_ptserver_tag(TEST_SERVER_ID);
885    TEST_ASSERT_NO_ERROR(arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag));
886
887    const char *servername = GBS_read_arb_tcp(server_tag);;
888    TEST_ASSERT_EQUAL(servername, "localhost:3200"); // as defined in ../lib/arb_tcp.dat@ARB_TEST_PT_SERVER
889
890    long com;
891    long locs;
892    aisc_com *link = aisc_open(servername, &com, AISC_MAGIC_NUMBER);
893    TEST_ASSERT(link);
894
895    TEST_ASSERT_ZERO(aisc_create(link, PT_MAIN, com,
896                                 MAIN_LOCS, PT_LOCS, &locs,
897                                 NULL));
898
899    {
900#define LOCAL(rvar) (prev_read_##rvar)
901
902       
903#define FREE_LOCAL_long(rvar)
904#define FREE_LOCAL_charp(rvar) free(LOCAL(rvar))
905#define FREE_LOCAL(type,rvar) FREE_LOCAL_##type(rvar)
906
907#define TEST__READ(type,rvar,expected)                                  \
908        do {                                                            \
909            TEST_ASSERT_ZERO(aisc_get(link, PT_LOCS, locs, rvar, &(LOCAL(rvar)), NULL)); \
910            TEST_ASSERT_EQUAL(LOCAL(rvar), expected);                   \
911            FREE_LOCAL(type,rvar);                                      \
912        } while(0)
913#define TEST_WRITE(type,rvar,val)                                       \
914        TEST_ASSERT_ZERO(aisc_put(link, PT_LOCS, locs, rvar, (type)val, NULL))
915#define TEST_CHANGE(type,rvar,val)              \
916        do {                                    \
917            TEST_WRITE(type, rvar, val);        \
918            TEST__READ(type, rvar, val);        \
919        } while(0)
920#define TEST_DEFAULT_CHANGE(ctype,type,remote_variable,default_value,other_value) \
921        do {                                                            \
922            ctype DEFAULT_VALUE = default_value;                   \
923            ctype OTHER_VALUE   = other_value;                     \
924            type LOCAL(remote_variable);                                \
925            TEST__READ(type, remote_variable, DEFAULT_VALUE);           \
926            TEST_CHANGE(type, remote_variable, OTHER_VALUE);            \
927            TEST_CHANGE(type, remote_variable, DEFAULT_VALUE);          \
928        } while(0)
929
930        TEST_DEFAULT_CHANGE(const long, long, LOCS_MATCH_REVERSED, 1, 67);
931        typedef char *charp;
932        typedef const char *ccharp;
933        TEST_DEFAULT_CHANGE(ccharp, charp, LOCS_LOGINTIME, "notime", "sometime");
934    }
935
936    TEST_ASSERT_ZERO(aisc_close(link));
937}
938
939#endif
Note: See TracBrowser for help on using the repository browser.