~ubuntu-branches/ubuntu/intrepid/primer3/intrepid

« back to all changes in this revision

Viewing changes to src/format_output.c

  • Committer: Bazaar Package Importer
  • Author(s): Charles Plessy
  • Date: 2006-09-28 20:18:54 UTC
  • Revision ID: james.westby@ubuntu.com-20060928201854-45pwapz5e3a6d684
Tags: upstream-1.0b
ImportĀ upstreamĀ versionĀ 1.0b

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 1996,1997,1998,1999,2000,2001,2004,2006
 
3
Whitehead Institute for Biomedical Research, Steve Rozen
 
4
(http://jura.wi.mit.edu/rozen), and Helen Skaletsky
 
5
All rights reserved.
 
6
 
 
7
Redistribution and use in source and binary forms, with or without
 
8
modification, are permitted provided that the following conditions are
 
9
met:
 
10
 
 
11
   * Redistributions of source code must retain the above copyright
 
12
notice, this list of conditions and the following disclaimer.
 
13
   * Redistributions in binary form must reproduce the above
 
14
copyright notice, this list of conditions and the following disclaimer
 
15
in the documentation and/or other materials provided with the
 
16
distribution.
 
17
   * Neither the names of the copyright holders nor contributors may
 
18
be used to endorse or promote products derived from this software
 
19
without specific prior written permission.
 
20
 
 
21
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
24
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
25
OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
26
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
27
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
28
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
29
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
30
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
31
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
32
*/
 
33
 
 
34
#include <stdio.h>
 
35
#include <string.h>
 
36
#include "format_output.h"
 
37
#include "primer3_release.h"
 
38
 
 
39
#define FORWARD 1
 
40
#define REVERSE -1
 
41
 
 
42
static int lib_sim_specified(const primer_args *);
 
43
static void print_explain(FILE *, const primer_args *,
 
44
                          const seq_args *, int);
 
45
static void print_pair_info(FILE *, const primer_pair *,
 
46
                            const primer_args *);
 
47
static void print_oligo(FILE *, const char *, const seq_args *,
 
48
                        const primer_rec *, int, const primer_args *, 
 
49
                        const seq_lib, int);
 
50
static void print_oligo_header(FILE *, const char *, const int);
 
51
static void print_pair_array(FILE *, const char*, int,
 
52
                             const interval_array_t, 
 
53
                             const primer_args*, const seq_args*);
 
54
static void print_rest(FILE *, const primer_args *, 
 
55
                       const seq_args *,  const pair_array_t *);
 
56
static void print_seq(FILE *, const primer_args *, const seq_args *, 
 
57
                            primer_rec *h, const pair_array_t *, int);
 
58
static void print_seq_lines(FILE *, const char *s, const char *n, int, int,
 
59
                            int, const primer_args *);
 
60
static void print_stat_line(FILE *, const char *, oligo_stats s, int);
 
61
static void print_summary(FILE *, const primer_args *, 
 
62
                          const seq_args *, const pair_array_t *, int);
 
63
static void print_oligo_summary(FILE *, const primer_args *, 
 
64
                          const seq_args *, primer_rec *, 
 
65
                          oligo_type, int);
 
66
 
 
67
 
 
68
void
 
69
format_pairs(f, pa, sa, best_pairs)
 
70
    FILE *f;
 
71
    const primer_args *pa;
 
72
    const seq_args *sa;
 
73
    const pair_array_t *best_pairs;
 
74
{
 
75
    char *warning;
 
76
    int print_lib_sim = lib_sim_specified(pa);
 
77
    primer_rec *h;
 
78
 
 
79
    PR_ASSERT(NULL != f);
 
80
    PR_ASSERT(NULL != pa);
 
81
    PR_ASSERT(NULL != sa);
 
82
 
 
83
    h = NULL;
 
84
    if (NULL != sa->sequence_name)
 
85
        fprintf(f, "PRIMER PICKING RESULTS FOR %s\n\n", sa->sequence_name);
 
86
 
 
87
    if (sa->error.data != NULL) 
 
88
        fprintf(f, "INPUT PROBLEM: %s\n\n", sa->error.data);
 
89
    else {
 
90
        if (pa->repeat_lib.repeat_file != NULL)
 
91
            fprintf(f, "Using mispriming library %s\n",
 
92
                    pa->repeat_lib.repeat_file);
 
93
        else
 
94
            fprintf(f, "No mispriming library specified\n");
 
95
 
 
96
        if ( pa->primer_task == 1) {
 
97
          if (pa->io_mishyb_library.repeat_file != NULL)
 
98
            fprintf(f, "Using internal oligo mishyb library %s\n",
 
99
                    pa->io_mishyb_library.repeat_file);
 
100
          else
 
101
            fprintf(f, "No internal oligo mishyb library specified\n");
 
102
        }
 
103
 
 
104
        fprintf(f, "Using %d-based sequence positions\n",
 
105
                pa->first_base_index);
 
106
        if (best_pairs->num_pairs == 0) fprintf(f, "NO PRIMERS FOUND\n\n");
 
107
        if ((warning = pr_gather_warnings(sa, pa)) != NULL) {
 
108
          fprintf(f, "WARNING: %s\n\n", warning);
 
109
          free(warning);
 
110
        }
 
111
        print_summary(f, pa, sa, best_pairs, 0);
 
112
        fprintf(f, "\n");
 
113
 
 
114
        print_seq(f, pa, sa, h, best_pairs, 0);
 
115
        if (best_pairs->num_pairs > 1 ) print_rest(f, pa, sa, best_pairs);
 
116
        if (pa->explain_flag) print_explain(f, pa, sa, print_lib_sim);
 
117
        fprintf(f, "\n\n");
 
118
        if (fflush(f) == EOF) {
 
119
          perror("fflush(f) failed");
 
120
          exit(-1);
 
121
        }
 
122
    }
 
123
}
 
124
 
 
125
static void
 
126
print_summary(f, pa, sa, best_pairs, num)
 
127
    FILE *f;
 
128
    const primer_args *pa;
 
129
    const seq_args *sa;
 
130
    const pair_array_t *best_pairs;
 
131
    int num;
 
132
{
 
133
    int seq_len = strlen(sa->sequence);
 
134
    int print_lib_sim = lib_sim_specified(pa);
 
135
    primer_pair *p;
 
136
    p = best_pairs->pairs + num;
 
137
    if (best_pairs->num_pairs > 0) {
 
138
        /* 
 
139
         * If the following format changes, also change the format in
 
140
         * print_oligo.
 
141
         */
 
142
        print_oligo_header(f, "OLIGO", print_lib_sim);
 
143
        print_oligo(f, "LEFT PRIMER", sa, p->left, FORWARD, pa, pa->repeat_lib,
 
144
                    print_lib_sim);
 
145
        print_oligo(f, "RIGHT PRIMER", sa, p->right, REVERSE, pa, pa->repeat_lib,
 
146
                    print_lib_sim);
 
147
        if ( pa->primer_task == 1)
 
148
            print_oligo(f, "INTERNAL OLIGO", sa, p->intl, FORWARD, pa, pa->io_mishyb_library,
 
149
                        print_lib_sim);
 
150
    }
 
151
    fprintf(f, "SEQUENCE SIZE: %d\n", seq_len);
 
152
    fprintf(f, "INCLUDED REGION SIZE: %d\n\n", sa->incl_l);
 
153
 
 
154
    if (best_pairs->num_pairs > 0) print_pair_info(f, p, pa);
 
155
    print_pair_array(f, "TARGETS", sa->num_targets, sa->tar, pa, sa);
 
156
    print_pair_array(f, "EXCLUDED REGIONS", sa->num_excl, sa->excl, pa, sa);
 
157
    print_pair_array(f, "INTERNAL OLIGO EXCLUDED REGIONS",
 
158
                     sa->num_internal_excl, sa->excl_internal, pa, sa);
 
159
}
 
160
 
 
161
/* Print column headers for lines printed by print_oligo(). */
 
162
static void
 
163
print_oligo_header(f, s, print_lib_sim)
 
164
    FILE *f;
 
165
    const char *s;
 
166
    const int print_lib_sim;
 
167
{
 
168
    fprintf(f,
 
169
            "%-16s start  len      tm     gc%%   any    3' %sseq\n",
 
170
            s, print_lib_sim ? "  rep " : "");
 
171
}
 
172
 
 
173
static void
 
174
print_oligo(f, title, sa, o, dir, pa, seqlib, print_lib_sim)
 
175
    FILE *f;
 
176
    const char *title;
 
177
    const seq_args *sa;
 
178
    const primer_rec *o;
 
179
    int dir;
 
180
    const primer_args *pa;
 
181
    const seq_lib seqlib;
 
182
    int print_lib_sim;
 
183
{
 
184
    const char *format1 = "%-16s %5d %4d %7.2f %7.2f %5.2f %5.2f ";
 
185
    char *seq = (FORWARD == dir) 
 
186
        ? pr_oligo_sequence(sa, o) : pr_oligo_rev_c_sequence(sa, o);
 
187
 
 
188
    fprintf(f, format1,
 
189
            title, o->start + sa->incl_s + pa->first_base_index,
 
190
            o->length, o->temp, o->gc_content, 0.01 * o->self_any,
 
191
            0.01 * o->self_end);
 
192
 
 
193
    if (print_lib_sim) {
 
194
        if (seqlib.repeat_file) 
 
195
            fprintf(f, "%5.2f ",  0.01 * o->repeat_sim.score[o->repeat_sim.max]);
 
196
        else 
 
197
            fprintf(f, "%5s ", "");
 
198
    }
 
199
    fprintf(f, "%s\n", seq);
 
200
    if (PR_DEFAULT_INSIDE_PENALTY != pa->inside_penalty
 
201
        || PR_DEFAULT_OUTSIDE_PENALTY != pa->outside_penalty)
 
202
      fprintf(f, "POSITION PENALTY, QUALITY: %f, %f\n",
 
203
              o->position_penalty, o->quality);
 
204
}
 
205
 
 
206
static void
 
207
print_pair_array(f, title, num, array, pa, sa)
 
208
    FILE *f;
 
209
    const char* title;
 
210
    int num;
 
211
    const interval_array_t array;
 
212
    const primer_args *pa;
 
213
    const seq_args *sa;
 
214
{
 
215
    int j;
 
216
    if (num > 0) {
 
217
        fprintf(f, "%s (start, len)*:", title);
 
218
        for (j = 0; j < num; j++)
 
219
            fprintf(f, " %d,%d", 
 
220
                    array[j][0] + pa->first_base_index + sa->incl_s,
 
221
                    array[j][1]);
 
222
        fprintf(f, "\n");
 
223
    }
 
224
}
 
225
 
 
226
#define VECTOR           (1<<0)
 
227
#define LEFT_OLIGO       (1<<1)
 
228
#define RIGHT_OLIGO      (1<<2)
 
229
#define INTL_OLIGO       (1<<3)
 
230
#define TARGET           (1<<4)
 
231
#define EXCL_REGION      (1<<5)
 
232
#define INTL_EXCL_REGION (1<<6)
 
233
 
 
234
static void
 
235
print_seq(f, pa, sa, h, best_pairs, num)
 
236
    FILE *f;
 
237
    const primer_args *pa;
 
238
    const seq_args *sa;
 
239
    primer_rec *h;
 
240
    const pair_array_t *best_pairs;
 
241
    int num;  /* The number of primer pair to print. */
 
242
{
 
243
    int len, i, j, start;
 
244
    int something_found = 0, vector_found = 0;
 
245
    int *notes;
 
246
    char *notestr;
 
247
    primer_pair *p;
 
248
    p = NULL;
 
249
    if(pa->primer_task == pick_pcr_primers ||
 
250
       pa->primer_task == pick_pcr_primers_and_hyb_probe)
 
251
                                      p = best_pairs->pairs + num;
 
252
    len = strlen(sa->sequence);
 
253
    notes = pr_safe_malloc(sizeof(*notes) * len);
 
254
    memset(notes, 0, sizeof(*notes) * len);
 
255
    notestr = pr_safe_malloc(len + 1);
 
256
    memset(notestr, ' ', len);
 
257
    notestr[len] = '\0';
 
258
 
 
259
    for (i = 0; i < len; i++) {
 
260
        if (i < sa->incl_s || i >= sa->incl_s + sa->incl_l)
 
261
            notes[i] |= VECTOR;
 
262
 
 
263
        if ((pa->primer_task == pick_pcr_primers ||
 
264
            pa->primer_task == pick_pcr_primers_and_hyb_probe) &&
 
265
            best_pairs->num_pairs > 0) {
 
266
            if (i >= p->left->start + sa->incl_s
 
267
                && i < p->left->start + p->left->length + sa->incl_s)
 
268
                notes[i] |= LEFT_OLIGO;
 
269
            if (i >= p->right->start - p->right->length + 1 + sa->incl_s
 
270
                && i <= p->right->start + sa->incl_s)
 
271
                notes[i] |= RIGHT_OLIGO;
 
272
            if ( pa->primer_task == 1
 
273
                && i >= p->intl->start + sa->incl_s 
 
274
                && i < p->intl->start + p->intl->length + sa->incl_s)
 
275
                notes[i] |= INTL_OLIGO;
 
276
        }
 
277
        else if (h != NULL) {
 
278
            if(pa->primer_task == pick_left_only &&
 
279
               i < h->start + h->length + sa->incl_s &&
 
280
               i >= h->start + sa->incl_s)
 
281
               notes[i] |= LEFT_OLIGO;
 
282
            else if(pa->primer_task == pick_right_only &&
 
283
               i >= h->start - h->length + 1 + sa->incl_s
 
284
               && i <= h->start + sa->incl_s)
 
285
               notes[i] |= RIGHT_OLIGO;
 
286
            else if(pa->primer_task == pick_hyb_probe_only &&
 
287
                 i >= h->start + sa->incl_s                &&
 
288
                 i < h->start + h->length + sa->incl_s)
 
289
               notes[i] |= INTL_OLIGO;
 
290
        }
 
291
 
 
292
        for (j = 0; j < sa->num_targets; j++) {
 
293
            start = sa->tar[j][0] + sa->incl_s;
 
294
            if (i >= start && i < start + sa->tar[j][1])
 
295
                notes[i] |= TARGET;
 
296
        }
 
297
        for (j = 0; j < sa->num_excl; j++) {
 
298
            start = sa->excl[j][0] + sa->incl_s;
 
299
            if (i >= start && i < start + sa->excl[j][1])
 
300
                notes[i] |= EXCL_REGION;
 
301
        }
 
302
        for (j = 0; j < sa->num_internal_excl; j++) {
 
303
            start = sa->excl_internal[j][0] + sa->incl_s;
 
304
            if (i >= start && i < start + sa->excl_internal[j][1])
 
305
                notes[i] |= INTL_EXCL_REGION;
 
306
        }
 
307
    }
 
308
 
 
309
    for (i = 0; i < len; i++) {
 
310
        if (notes[i] & VECTOR) {
 
311
            vector_found = 1;
 
312
            notestr[i] = '.';
 
313
        }
 
314
        else if (notes[i] & EXCL_REGION)
 
315
            notestr[i] = 'X';
 
316
        else if (notes[i] & INTL_EXCL_REGION)
 
317
            notestr[i] = 'x';
 
318
        else if ((notes[i] & TARGET) && (notes[i] & LEFT_OLIGO))
 
319
          notestr[i] = ')';
 
320
        else if ((notes[i] & TARGET) && (notes[i] & RIGHT_OLIGO))
 
321
          notestr[i] = '(';
 
322
        else if (notes[i] & TARGET)
 
323
            notestr[i] = '*';
 
324
        else if (notes[i] & LEFT_OLIGO)
 
325
            notestr[i] = '>';
 
326
        else if (notes[i] & RIGHT_OLIGO)
 
327
            notestr[i] = '<';
 
328
        else if (notes[i] & INTL_OLIGO)
 
329
            notestr[i] = '^';
 
330
 
 
331
        if (notes[i] != 0) something_found = 1;
 
332
    }
 
333
 
 
334
    print_seq_lines(f, sa->sequence, notestr, len, 60, something_found, pa);
 
335
 
 
336
    if (something_found)
 
337
        fprintf(f, "KEYS (in order of precedence):\n");
 
338
 
 
339
    if (vector_found)
 
340
        fprintf(f, "...... vector sequence\n");
 
341
 
 
342
    if (sa->num_excl > 0)
 
343
        fprintf(f, "XXXXXX excluded region\n");
 
344
 
 
345
    if (pa->primer_task == 1
 
346
        && sa->num_internal_excl > 0)
 
347
        fprintf(f, "xxxxxx excluded region for internal oligo\n");
 
348
 
 
349
    if (sa->num_targets > 0)
 
350
        fprintf(f, "****** target\n");
 
351
 
 
352
    if ((pa->primer_task == pick_pcr_primers ||
 
353
        pa->primer_task == pick_pcr_primers_and_hyb_probe) &&
 
354
        best_pairs->num_pairs > 0) {
 
355
           fprintf(f, ">>>>>> left primer\n");
 
356
           fprintf(f, "<<<<<< right primer\n");
 
357
           if ( pa->primer_task == 1)
 
358
              fprintf(f, "^^^^^^ internal oligo\n");
 
359
    }
 
360
    else if (pa->primer_task == pick_left_only && h != NULL)
 
361
           fprintf(f, ">>>>>> left primer\n");
 
362
    else if (pa->primer_task == pick_right_only && h != NULL)
 
363
           fprintf(f, "<<<<<< right primer\n");
 
364
    else if (pa->primer_task == pick_hyb_probe_only && h != NULL)
 
365
           fprintf(f, "^^^^^^ internal oligo\n");
 
366
 
 
367
    if (something_found) fputc('\n', f);
 
368
    free(notes);
 
369
    free(notestr);
 
370
}
 
371
 
 
372
static void
 
373
print_seq_lines(f, s, n, seq_size, line_size, something_found, pa)
 
374
    FILE *f;
 
375
    const char *s, *n;
 
376
    int seq_size, line_size, something_found;
 
377
    const primer_args *pa;
 
378
{
 
379
    int i = 0;
 
380
    while (seq_size > line_size) {
 
381
        fprintf(f, "%5d ", i + pa->first_base_index);
 
382
        fwrite(s, sizeof(*s), line_size, f);
 
383
        fputc('\n', f);
 
384
        if (something_found) {
 
385
            fprintf(f, "      ");
 
386
            fwrite(n, sizeof(*n), line_size, f);
 
387
            fprintf(f, "\n\n");
 
388
        }
 
389
        seq_size -= line_size;
 
390
        s += line_size;
 
391
        n += line_size;
 
392
        i += line_size;
 
393
    }
 
394
    if (something_found)
 
395
        fprintf(f, "%5d %s\n      %s\n\n", i + pa->first_base_index, s, n);
 
396
    else
 
397
        fprintf(f, "%5d %s\n\n", i + pa->first_base_index, s);
 
398
}
 
399
 
 
400
static void
 
401
print_pair_info(f, p, pa)
 
402
    FILE *f;
 
403
    const primer_pair *p;
 
404
    const primer_args *pa;
 
405
{
 
406
  fprintf(f, "PRODUCT SIZE: %d, ", p->product_size);
 
407
  fprintf(f, "PAIR ANY COMPL: %.2f, PAIR 3' COMPL: %.2f\n",
 
408
          0.01 * p->compl_any, 0.01 * p->compl_end);
 
409
 
 
410
  if (pa->product_max_tm != PR_DEFAULT_PRODUCT_MAX_TM
 
411
      || pa->product_min_tm != PR_DEFAULT_PRODUCT_MIN_TM) {
 
412
    printf("PRODUCT Tm: %.4f, ", p->product_tm);
 
413
    printf("PRODUCT Tm - min(OLIGO Tm): %.4f\n",
 
414
           p->product_tm_oligo_tm_diff);
 
415
  }
 
416
}
 
417
 
 
418
static void
 
419
print_rest(f, pa, sa, best_pairs)
 
420
    FILE *f;
 
421
    const primer_args *pa;
 
422
    const seq_args *sa;
 
423
    const pair_array_t *best_pairs;
 
424
{
 
425
    int i;
 
426
    int print_lib_sim = lib_sim_specified(pa);
 
427
 
 
428
    fprintf(f, "ADDITIONAL OLIGOS\n");
 
429
    fprintf(f, "   "); print_oligo_header(f, "", print_lib_sim);
 
430
    for (i = 1; i < best_pairs->num_pairs; i++) {
 
431
        fprintf(f, "\n%2d ", i);
 
432
        print_oligo(f, "LEFT PRIMER", sa, best_pairs->pairs[i].left, FORWARD,
 
433
                    pa, pa->repeat_lib, print_lib_sim);
 
434
        fprintf(f, "   ");
 
435
        print_oligo(f, "RIGHT PRIMER", sa, best_pairs->pairs[i].right, REVERSE,
 
436
                    pa, pa->repeat_lib, print_lib_sim);
 
437
        if ( pa->primer_task == 1) {
 
438
            fprintf(f, "   ");
 
439
            print_oligo(f, "INTERNAL OLIGO", sa, best_pairs->pairs[i].intl,
 
440
                        FORWARD, pa, pa->io_mishyb_library, print_lib_sim);
 
441
        }
 
442
        if (best_pairs->pairs[i].product_size > 0) {
 
443
            fprintf(f, "   ");
 
444
            print_pair_info(f, &best_pairs->pairs[i], pa);
 
445
        }
 
446
    }
 
447
}
 
448
 
 
449
/* This function does _not_ print out the no_orf statistic. */
 
450
static void
 
451
print_explain(f, pa, sa, print_lib_sim)
 
452
    FILE *f;
 
453
    const primer_args *pa;
 
454
    const seq_args *sa;
 
455
    int print_lib_sim;
 
456
{
 
457
  const pair_stats *x;
 
458
  const char *format = print_lib_sim
 
459
    ? "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n"
 
460
    : "%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s\n";
 
461
 
 
462
  fprintf(f, "\nStatistics\n");
 
463
 
 
464
  if (!pa->pick_anyway
 
465
      || !((pick_pcr_primers == pa->primer_task 
 
466
           && sa->left_input && sa->right_input)
 
467
          || (pick_pcr_primers_and_hyb_probe == pa->primer_task
 
468
              && sa->left_input && sa->right_input && sa->internal_input)
 
469
          || (pick_left_only == pa->primer_task
 
470
              && sa->left_input)
 
471
          || (pick_right_only == pa->primer_task
 
472
              && sa->right_input)
 
473
          || (pick_hyb_probe_only == pa->primer_task
 
474
              && sa->internal_input))) {
 
475
 
 
476
    if (print_lib_sim) {
 
477
      fprintf(f, format,
 
478
              "", "con", "too",  "in",  "in",  "",    "no",
 
479
              "tm",  "tm",  "high", "high", "high",
 
480
              "", "high", "");
 
481
      fprintf(f, format,
 
482
              "", "sid", "many", "tar", "excl", "bad","GC",
 
483
              "too", "too", "any",  "3'", "lib",
 
484
              "poly", "end", "");
 
485
      fprintf(f, format,
 
486
              "", "ered","Ns",   "get", "reg",  "GC%", "clamp",
 
487
              "low", "high","compl", "compl", "sim",
 
488
              "X",  "stab", "ok");
 
489
    } else {
 
490
      fprintf(f, format,
 
491
              "", "con", "too",  "in",  "in",  "",    "no",
 
492
              "tm",  "tm",  "high", "high",
 
493
              "", "high", "");
 
494
      fprintf(f, format,
 
495
              "", "sid", "many", "tar", "excl", "bad","GC",
 
496
              "too", "too", "any",  "3'",
 
497
              "poly", "end", "");
 
498
      fprintf(f, format,
 
499
              "", "ered","Ns",   "get", "reg",  "GC%", "clamp",
 
500
              "low", "high","compl", "compl",
 
501
              "X", "stab", "ok");
 
502
    }
 
503
 
 
504
  }
 
505
 
 
506
  if ((pick_pcr_primers == pa->primer_task
 
507
       || pick_left_only == pa->primer_task
 
508
       || pick_pcr_primers_and_hyb_probe == pa->primer_task)
 
509
      && !(pa->pick_anyway && sa->left_input))
 
510
    print_stat_line(f, "Left", sa->left_expl, print_lib_sim);
 
511
 
 
512
  if ((pick_pcr_primers == pa->primer_task
 
513
       || pick_right_only  == pa->primer_task
 
514
       || pick_pcr_primers_and_hyb_probe == pa->primer_task)
 
515
      && !(pa->pick_anyway && sa->right_input))
 
516
    print_stat_line(f, "Right", sa->right_expl, print_lib_sim);
 
517
 
 
518
  if ((pick_pcr_primers_and_hyb_probe == pa->primer_task
 
519
       || pick_hyb_probe_only == pa->primer_task)
 
520
      && !(pa->pick_anyway && sa->internal_input))
 
521
    print_stat_line(f, "Intl", sa->intl_expl, print_lib_sim);
 
522
 
 
523
  if (pick_pcr_primers == pa->primer_task
 
524
      || pick_pcr_primers_and_hyb_probe == pa->primer_task) {
 
525
    fprintf(f, "Pair Stats:\n");
 
526
    x = &sa->pair_expl;
 
527
    pr_print_pair_explain(f, sa);
 
528
  }
 
529
  fprintf(f, "%s\n", pr_release);
 
530
}
 
531
 
 
532
static void
 
533
print_stat_line(f, t, s, print_lib_sim)
 
534
    FILE *f;
 
535
    const char *t;
 
536
    oligo_stats s;
 
537
    int print_lib_sim;
 
538
{
 
539
    const char *format = print_lib_sim
 
540
        ? "%-6s%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d\n"
 
541
        : "%-6s%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d\n";
 
542
 
 
543
    if (print_lib_sim)
 
544
        fprintf(f, format,
 
545
                t, s.considered, s.ns, s.target, s.excluded,
 
546
                s.gc, s.gc_clamp, s.temp_min, s.temp_max,
 
547
                s.compl_any, s.compl_end, s.repeat_score,
 
548
                s.poly_x, s.stability, s.ok);
 
549
    else 
 
550
        fprintf(f, format,
 
551
                t, s.considered, s.ns, s.target, s.excluded,
 
552
                s.gc, s.gc_clamp, s.temp_min, s.temp_max,
 
553
                s.compl_any, s.compl_end, s.poly_x, s.stability, s.ok);
 
554
}
 
555
 
 
556
/* 
 
557
 * Return true iff a check for library similarity has been specified for
 
558
 * either the primer pair or the internal oligo.
 
559
 */
 
560
 
 
561
static int
 
562
lib_sim_specified(pa)
 
563
  const primer_args *pa;
 
564
{
 
565
  return (pa->repeat_lib.repeat_file || pa->io_mishyb_library.repeat_file);
 
566
}
 
567
 
 
568
void format_oligos(f, pa, sa, h, n, l)
 
569
   FILE *f;
 
570
   const primer_args *pa;
 
571
   const seq_args    *sa;
 
572
   primer_rec  *h;
 
573
   int n;
 
574
   oligo_type l;
 
575
{
 
576
  char *warning;
 
577
  int print_lib_sim = lib_sim_specified(pa);
 
578
  int i;
 
579
  pair_array_t *best_pairs;
 
580
  primer_rec *p;
 
581
  char type[20];
 
582
 
 
583
  PR_ASSERT(NULL != f);
 
584
  PR_ASSERT(NULL != pa);
 
585
  PR_ASSERT(NULL != sa);
 
586
 
 
587
  best_pairs = NULL;
 
588
  if (NULL != sa->sequence_name)
 
589
    fprintf(f, "PRIMER PICKING RESULTS FOR %s\n\n", sa->sequence_name);
 
590
 
 
591
  if (sa->error.data != NULL) 
 
592
    fprintf(f, "INPUT PROBLEM: %s\n\n", sa->error.data);
 
593
  else {
 
594
    if (l != OT_INTL ) {
 
595
      if (pa->repeat_lib.repeat_file != NULL)
 
596
        fprintf(f, "Using mispriming library %s\n",
 
597
                pa->repeat_lib.repeat_file);
 
598
      else
 
599
        fprintf(f, "No mispriming library specified\n");
 
600
    } else {
 
601
      if ( pa->primer_task == 1) {
 
602
        if (pa->io_mishyb_library.repeat_file != NULL)
 
603
          fprintf(f, "Using internal oligo mishyb library %s\n",
 
604
                  pa->io_mishyb_library.repeat_file);
 
605
        else
 
606
          fprintf(f, "No internal oligo mishyb library specified\n");
 
607
      }
 
608
    }
 
609
 
 
610
    if(l == OT_LEFT) strcpy(type, "LEFT_PRIMER");
 
611
    else if(l == OT_RIGHT) strcpy(type, "RIGHT_PRIMER");
 
612
    else strcpy(type, "INTERNAL_OLIGO");
 
613
 
 
614
    fprintf(f, "Using %d-based sequence positions\n",
 
615
            pa->first_base_index);
 
616
    if (n == 0) fprintf(f, "NO OLIGOS FOUND\n\n");
 
617
    if ((warning = pr_gather_warnings(sa, pa)) != NULL) {
 
618
      fprintf(f, "WARNING: %s\n\n", warning);
 
619
      free(warning);
 
620
    }
 
621
 
 
622
    if(n > 0) print_oligo_summary(f, pa, sa, h, l, 0);
 
623
    else h = NULL;
 
624
    print_seq(f, pa, sa, h, best_pairs, 0);
 
625
    fprintf(f, "\n");
 
626
    if(n > 1) {
 
627
      fprintf(f, "ADDITIONAL OLIGOS\n");
 
628
      fprintf(f, "   "); print_oligo_header(f, "", print_lib_sim);
 
629
      for(i = 1; i < pa->num_return; i++) {
 
630
        if(i > n-1) break;
 
631
        p = h + i;
 
632
        fprintf(f, "%2d ", i);
 
633
        if(OT_LEFT == l || OT_INTL == l)
 
634
          print_oligo(f, type, sa, p, FORWARD,pa, pa->repeat_lib, print_lib_sim);
 
635
        else   print_oligo(f, type, sa, p, REVERSE,pa, pa->repeat_lib, print_lib_sim);
 
636
      }
 
637
    }
 
638
    if(pa->explain_flag) print_explain(f, pa, sa, print_lib_sim);
 
639
    fprintf(f, "\n\n");
 
640
    if (fflush(f) == EOF) {
 
641
      perror("fflush(f) failed");
 
642
      exit(-1);
 
643
    }
 
644
  }
 
645
}
 
646
 
 
647
static void
 
648
print_oligo_summary(f, pa, sa, h, l, num)
 
649
    FILE *f;
 
650
    const primer_args *pa;
 
651
    const seq_args *sa;
 
652
    primer_rec *h;
 
653
    oligo_type l;
 
654
    int num;
 
655
{
 
656
    int seq_len = strlen(sa->sequence);
 
657
    int print_lib_sim = lib_sim_specified(pa);
 
658
    primer_rec *p;
 
659
    char type[20];
 
660
 
 
661
    if(l == OT_LEFT) strcpy(type, "LEFT_PRIMER");
 
662
    else if(l == OT_RIGHT) strcpy(type, "RIGHT_PRIMER");
 
663
    else strcpy(type, "INTERNAL_OLIGO");
 
664
 
 
665
    p = h + num;
 
666
        /* 
 
667
         * If the following format changes, also change the format in
 
668
         * print_oligo.
 
669
         */
 
670
    print_oligo_header(f, "OLIGO", print_lib_sim);
 
671
    if(OT_LEFT == l || OT_INTL == l)
 
672
            print_oligo(f, type, sa, p, FORWARD, pa, pa->repeat_lib,
 
673
                    print_lib_sim);
 
674
    else print_oligo(f, type, sa, p, REVERSE, pa, pa->repeat_lib,
 
675
                    print_lib_sim);
 
676
    
 
677
    fprintf(f, "SEQUENCE SIZE: %d\n", seq_len);
 
678
    fprintf(f, "INCLUDED REGION SIZE: %d\n\n", sa->incl_l);
 
679
 
 
680
    print_pair_array(f, "TARGETS", sa->num_targets, sa->tar, pa, sa);
 
681
    print_pair_array(f, "EXCLUDED REGIONS", sa->num_excl, sa->excl, pa, sa);
 
682
    print_pair_array(f, "INTERNAL OLIGO EXCLUDED REGIONS",
 
683
                     sa->num_internal_excl, sa->excl_internal, pa, sa);
 
684
}
 
685