/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "dotmat.p" */ #include /* dotmat: dot matricies of two books by Thomas Schneider from module libraries: delman, delmods, prgmods (modules correspond to program matrix) */ /* end of program */ /* begin module version */ #define version 3.08 /* of dotmat 1994 sep 5 */ /* end module version */ /* begin module describe.dotmat */ /* name dotmat: dot matrices of two books synopsis dotmat(xbook: in, ybook: in, mlist: out, dotmatp: in, output: out) files xbook: a book from the delila system ybook: a book from the delila system mlist: a dot matrix for each sequence pair between the two books. the "dots" are printed as numbers: 1 means gt base pair 2 means at base pair 3 means gc base pair xbook sequences are written down the page and those of ybook go across the page. if mlist is wider than your printer, use the split program. dotmatp: parameters to control the mlist. if dotmatp is empty, default values are used. otherwise if the first line begins with a "g" then g-u pairs are printed. output: messages to the user description dotmat produces a dot matrix for all complementary base pairs between all pairs of sequences in the two books. because a list of helices is not made, the program is much more efficient for short minimum helices than is the pair of programs helix and matrix. documentation delman.use.comparison J. V. Maizel, Jr. and R. P. Lenk PNAS 78: 7665-7609 (1981) see also helix.p, matrix.p, split.p author thomas d. schneider bugs none known */ /* end module describe.dotmat */ /* more constants: */ #define nodot ':' /* the character to print for background, note: it must not blank, so that the user can align the helices by the numbers. */ #define prime '\'' /* single quote */ #define pagelength 48 /* lines printed of dotmat on one page in mlist */ /* begin module book.const */ /* constants needed for book manipulations */ #define dnamax 3000 /* length of dna arrays */ #define namelength 20 /* maximum key name length */ #define linelength 80 /* maximum line readable in book */ /* end module book.const version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.type */ /* types needed for book manipulations */ typedef long chset[5]; /* types defined in book definition */ typedef Char alpha[namelength]; /* this is not alfa */ /* name is a left justified string with blanks following the characters */ typedef struct name { alpha letters; /* zero means an unspecified structure */ char length; } name; typedef struct line { /* a line of characters */ Char letters[linelength]; char length; struct line *next; } line; typedef enum { plus, minus, dircomplement, dirhomologous } direction; typedef enum { linear, circular } configuration; typedef enum { on, off } state; typedef struct header { /* header of key */ name keynam; /* key name of structure */ line *fulnam; /* full name of structure */ /* note key */ line *note; } header; /* base types */ typedef enum { a, c, g, t } base; typedef short dnarange; /* p2c: dotmat.p, line 123: * Note: Field width for seq assumes enum base has 4 elements [105] */ typedef uchar seq[(dnamax + 3) / 4]; typedef struct dnastring { seq part; dnarange length; struct dnastring *next; } dnastring; typedef struct orgkey { /* organism key */ header hea; /* genetic map units */ line *mapunit; } orgkey; typedef struct chrkey { /* chromosome key */ header hea; double mapbeg; /* number of genetic map beginning */ /* number of genetic map ending */ double mapend; } chrkey; typedef struct piekey { /* piece key */ header hea; double mapbeg; /* genetic map beginning */ configuration coocon; /* configruation (circular/linear) */ direction coodir; /* direction (+/-) relative to genetic map */ long coobeg; /* beginning nucleotide */ long cooend; /* ending nucleotide */ configuration piecon; /* configruation (circular/linear) */ direction piedir; /* direction (+/-) relative to coordinates */ long piebeg; /* beginning nucleotide */ long pieend; /* ending nucleotide */ } piekey; typedef struct piece { piekey key; dnastring *dna; } piece; typedef struct reference { name pienam; /* name of piece referred to */ double mapbeg; /* genetic map beginning */ direction refdir; /* direction relative to coordinates */ long refbeg; /* beginning nucleotide */ long refend; /* ending nucleotide */ } reference; typedef struct genkey { /* gene key */ header hea; reference ref; } genkey; typedef struct trakey { /* transcript key */ header hea; reference ref; } trakey; typedef struct markey { /* marker key */ header hea; reference ref; state sta; line *phenotype; struct marker *next; } markey; typedef struct marker { markey key; dnastring *dna; } marker; /* end module book.type version = 'delmod 6.54 86 nov 12 tds/gds' */ Static _TEXT xbook; /* one book */ Static _TEXT ybook; /* the other book */ Static _TEXT mlist; /* the dot matricies */ Static _TEXT dotmatp; /* parameters */ Static piece *xseq, *yseq; /* the sequences from the books */ Static long xnumber, ynumber; /* the numbers of the sequences */ Static boolean guallowed; /* true means gu pairs are allowed */ Static long xlength, ylength; /* of the sequences */ /* begin module book.var */ /* ************************************************************************ */ /* global variables needed for book manipulations */ /* free storage: */ Static line *freeline; /* unused lines */ Static dnastring *freedna; /* unused dnas */ Static boolean readnumber; /* whether to read a number from the notes, or to read in the notes */ Static long number; /* the number of the item just read */ Static boolean numbered; /* true when the item just read is numbered */ Static boolean skipunnum; Static jmp_buf _JL1; /* a control variable to allow skipping of un-numbered items in the book */ /* ************************************************************************ */ /* end module book.var version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module halt */ Static Void halt() { /* stop the program. the procedure performs a goto to the end of the program. you must have a label: label 1; declared, and also the end of the program must have this label: 1: end. examples are in the module libraries. this is the only goto in the delila system. */ printf(" program halt.\n"); longjmp(_JL1, 1); } /* end module halt version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module package.getpiece */ /* ************************************************************************ */ /* begin module package.brpiece */ /* ************************************************************************ */ /* begin module book.basis */ /* procedures needed for book manipulations */ /* get procedures should be used for all linked lists of records */ Static Void getline(l) line **l; { /* obtain a line from the free line list or by making a new one */ if (freeline != NULL) { *l = freeline; freeline = freeline->next; } else *l = (line *)Malloc(sizeof(line)); (*l)->length = 0; (*l)->next = NULL; } Static Void getdna(l) dnastring **l; { if (freedna != NULL) { *l = freedna; freedna = freedna->next; } else *l = (dnastring *)Malloc(sizeof(dnastring)); (*l)->length = 0; (*l)->next = NULL; } /* clear procedures should be called each time the records are no longer needed failure to do this may result in a stack overflow. */ Static Void clearline(l) line **l; { /* return a line to the free line list */ line *lptr; if (*l == NULL) return; lptr = *l; *l = (*l)->next; lptr->next = freeline; freeline = lptr; } Static Void cleardna(l) dnastring **l; { dnastring *lptr; if (*l == NULL) return; lptr = *l; *l = (*l)->next; lptr->next = freedna; freedna = lptr; } Static Void clearheader(h) header *h; { /* clear the header h (remove lines to free storage) */ clearline(&h->fulnam); while (h->note != NULL) clearline(&h->note); } Static Void clearpiece(p) piece **p; { /* clear the dna of the piece */ while ((*p)->dna != NULL) cleardna(&(*p)->dna); clearheader(&(*p)->key.hea); } Static base chartobase(ch) Char ch; { /* convert a character into a base */ base Result; switch (ch) { case 'a': Result = a; break; case 'c': Result = c; break; case 'g': Result = g; break; case 't': Result = t; break; } return Result; } Static Char basetochar(ba) base ba; { /* convert a base into a character */ Char Result; switch (ba) { case a: Result = 'a'; break; case c: Result = 'c'; break; case g: Result = 'g'; break; case t: Result = 't'; break; } return Result; } Static base complement(ba) base ba; { /* take the complement of ba */ base Result; switch (ba) { case a: Result = t; break; case c: Result = g; break; case g: Result = c; break; case t: Result = a; break; } return Result; } Static long pietoint(p, pie) long p; piece *pie; { /* p is a coordinate on the piece. we want to transform p into a number from 1 to n: an internal coordinate system for easy manipulation of piece coordinates */ long i; /* an intermediate value */ piekey *WITH; WITH = &pie->key; switch (WITH->piedir) { case plus: if (p >= WITH->piebeg) i = p - WITH->piebeg + 1; else i = p - WITH->coobeg + WITH->cooend - WITH->piebeg + 2; break; case minus: if (p <= WITH->piebeg) i = WITH->piebeg - p + 1; else i = WITH->cooend - p + WITH->piebeg - WITH->coobeg + 2; break; } return i; } Static long inttopie(i, pie) long i; piece *pie; { /* i is in the range 1 to some maximum. it is an internal coordinate system for the program. we want to do a coordinate transformation to obtain a value in the range of the piece called pie: i=1 corresponds to piebeg and i=its maximum corresponds to pieend */ long p; /* an intermediate value */ piekey *WITH; WITH = &pie->key; switch (WITH->piedir) { case plus: p = WITH->piebeg + i - 1; if (p > WITH->cooend) { if (WITH->coocon == circular) p += WITH->coobeg - WITH->cooend - 1; } break; case minus: p = WITH->piebeg - i + 1; if (p < WITH->coobeg) { if (WITH->coocon == circular) p += WITH->cooend - WITH->coobeg + 1; } break; } return p; } Static long piecelength(pie) piece *pie; { /* return the length of the dna in pie */ return (pietoint(pie->key.pieend, pie)); } /* end module book.basis version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.getto */ Static Char getto(thefile, ch) _TEXT *thefile; long *ch; { /* search the file for a character in the first line which is a member of the set ch. */ Char achar = ' '; while ((!P_inset(achar, ch)) & (!BUFEOF(thefile->f))) { fscanf(thefile->f, "%c%*[^\n]", &achar); getc(thefile->f); if (achar == '\n') achar = ' '; } if (P_inset(achar, ch)) return achar; else return ' '; } /* end module book.getto version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.skipstar */ Static Void skipstar(thefile) _TEXT *thefile; { /* skip start of line (or star = '*'). */ if (P_peek(thefile->f) != '*') { printf(" procedure skipstar: bad book\n"); printf(" \"*\" expected as first character on the line, but \"%c\" was found\n", P_peek(thefile->f)); halt(); } getc(thefile->f); /* skip the star */ if (P_peek(thefile->f) != ' ') { /* skip the blank */ printf(" procedure skipstar: bad book\n"); printf(" \"* \" expected on a line but \"*%c\" was found\n", P_peek(thefile->f)); halt(); } getc(thefile->f); } /* skipstar */ /* end module book.skipstar version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brreanum */ Static Void brreanum(thefile, reanum) _TEXT *thefile; double *reanum; { /* read a real number from the file */ skipstar(thefile); fscanf(thefile->f, "%lg%*[^\n]", reanum); getc(thefile->f); } /* end module book.brreanum version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brnumber */ Static Void brnumber(thefile, num) _TEXT *thefile; long *num; { /* read a number from the file */ skipstar(thefile); fscanf(thefile->f, "%ld%*[^\n]", num); getc(thefile->f); } /* end module book.brnumber version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brname */ Static Void brname(thefile, nam) _TEXT *thefile; name *nam; { /* read a name from the file */ long i; /* an index to the name */ Char c_; /* a character read */ skipstar(thefile); nam->length = 0; do { nam->length++; c_ = getc(thefile->f); if (c_ == '\n') c_ = ' '; nam->letters[nam->length - 1] = c_; } while (!(P_eoln(thefile->f) || nam->length >= namelength || nam->letters[nam->length - 1] == ' ')); if (nam->letters[nam->length - 1] == ' ') nam->length--; if (nam->length < namelength) { for (i = nam->length; i < namelength; i++) nam->letters[i] = ' '; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } /* brname */ /* end module book.brname version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brline */ Static Void brline(thefile, l) _TEXT *thefile; line **l; { /* read a line from the file */ long i = 0; long j; Char acharacter; long FORLIM; skipstar(thefile); while (!P_eoln(thefile->f)) { i++; acharacter = getc(thefile->f); if (acharacter == '\n') acharacter = ' '; (*l)->letters[i-1] = acharacter; } if (i < (*l)->length) { FORLIM = (*l)->length; for (j = i; j < FORLIM; j++) (*l)->letters[j] = ' '; } (*l)->length = i; (*l)->next = NULL; fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } /* end module book.brline version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brdirect */ Static Void brdirect(thefile, direct) _TEXT *thefile; direction *direct; { /* read a direction */ Char ch; skipstar(thefile); fscanf(thefile->f, "%c%*[^\n]", &ch); getc(thefile->f); if (ch == '\n') ch = ' '; if (ch == '+') *direct = plus; else *direct = minus; } /* end module book.brdirect version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brconfig */ Static Void brconfig(thefile, config) _TEXT *thefile; configuration *config; { /* read a configuration */ Char ch; skipstar(thefile); fscanf(thefile->f, "%c%*[^\n]", &ch); getc(thefile->f); if (ch == '\n') ch = ' '; if (ch == 'l') *config = linear; else *config = circular; } /* end module book.brconfig version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brnotenumber */ Static Void brnotenumber(thefile, note) _TEXT *thefile; line **note; { /* book note reading to obtain the number of the object. the procedure returns the value of the number as a global. (this is not such a good practice, but we are stuck with it for now.) */ *note = NULL; numbered = false; number = 0; /* force number to zero if there is no number at all */ /* the next character is n or * depending on whether there are notes */ if (P_peek(thefile->f) != 'n') return; fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); if (P_peek(thefile->f) == 'n') { fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); return; } skipstar(thefile); if (!P_eoln(thefile->f)) { if (P_peek(thefile->f) == '#') { numbered = true; getc(thefile->f); /* move past the number symbol */ fscanf(thefile->f, "%ld", &number); } } do { fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } while (P_peek(thefile->f) != 'n'); fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } /* brnotenumber */ /* end module book.brnotenumber version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brnote */ Static Void brnote(thefile, note) _TEXT *thefile; line **note; { /* read note key */ line *newnote; /* the new note */ line *previousnote; /* the last line of the notes */ *note = NULL; if (P_peek(thefile->f) != 'n') /* enter note */ return; fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); if (P_peek(thefile->f) == 'n') { /* abort null note (n/n) */ fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); return; } getline(note); newnote = *note; while (P_peek(thefile->f) != 'n') { /* wait until end of note */ brline(thefile, &newnote); previousnote = newnote; /* get next note */ getline(&newnote->next); newnote = newnote->next; } /* last note was not used, so: */ clearline(&newnote); previousnote->next = NULL; fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } /* brnote */ /* end module book.brnote version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brheader */ Static Void brheader(thefile, hea) _TEXT *thefile; header *hea; { /* read the header of a key. */ /* read key name */ brname(thefile, &hea->keynam); /* read full name */ getline(&hea->fulnam); brline(thefile, &hea->fulnam); /* read note key */ if (readnumber) brnotenumber(thefile, &hea->note); else brnote(thefile, &hea->note); } /* end module book.brheader version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brpiekey */ Static Void brpiekey(thefile, pie) _TEXT *thefile; piekey *pie; { /* read piece key */ brheader(thefile, &pie->hea); brreanum(thefile, &pie->mapbeg); brconfig(thefile, &pie->coocon); brdirect(thefile, &pie->coodir); brnumber(thefile, &pie->coobeg); brnumber(thefile, &pie->cooend); brconfig(thefile, &pie->piecon); brdirect(thefile, &pie->piedir); brnumber(thefile, &pie->piebeg); brnumber(thefile, &pie->pieend); } /* end module book.brpiekey version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brdna */ Static Void brdna(thefile, dna) _TEXT *thefile; dnastring **dna; { /* read in dna from thefile */ /* note: if the dna were circularized, by linking the last dnastring to the first, then the cleardna routine could not clear properly, and would loop forever... there is no reason to do that, since a simple mod function will allow one to access the circle. */ Char ch; dnastring *workdna; long SET[5]; long TEMP; getdna(dna); workdna = *dna; ch = getto(thefile, P_addset(P_expset(SET, 0L), 'd')); ch = getc(thefile->f); /* skipstar */ if (ch == '\n') ch = ' '; while (ch == '*') { ch = getc(thefile->f); /* skip blank */ if (ch == '\n') ch = ' '; do { ch = getc(thefile->f); if (ch == '\n') ch = ' '; if (ch == 't' || ch == 'g' || ch == 'c' || ch == 'a') { if (workdna->length == dnamax) { getdna(&workdna->next); workdna = workdna->next; } workdna->length++; TEMP = workdna->length - 1; P_clrbits_B(workdna->part, TEMP, 1, 3); P_putbits_UB(workdna->part, TEMP, (int)chartobase(ch), 1, 3); } } while (!P_eoln(thefile->f)); fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* go to next line */ ch = getc(thefile->f); /* ch is either '*' or 'd' */ if (ch == '\n') ch = ' '; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); } /* end module book.brdna version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brpiece */ Static Void brpiece(thefile, pie) _TEXT *thefile; piece **pie; { /* read in a piece */ brpiekey(thefile, &(*pie)->key); if (numbered || !skipunnum) brdna(thefile, &(*pie)->dna); } /* end module book.brpiece version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.brinit */ Static Void brinit(book) _TEXT *book; { /* check that the book is ok to read, and set up the global variables for br routines */ /* halt if the book is bad (first word is 'halt') or the first character is not * */ if (*book->name != '\0') { if (book->f != NULL) book->f = freopen(book->name, "r", book->f); else book->f = fopen(book->name, "r"); } else rewind(book->f); if (book->f == NULL) _EscIO2(FileNotFound, book->name); RESETBUF(book->f, Char); if (!BUFEOF(book->f)) { /* check for the date line */ if (P_peek(book->f) != '*') { if (P_peek(book->f) != 'h') printf(" this is not the first line of a book:\n"); else printf(" bad book:\n"); putchar(' '); while (!(P_eoln(book->f) | BUFEOF(book->f))) { putchar(P_peek(book->f)); getc(book->f); } putchar('\n'); halt(); } } else { printf(" book is empty\n"); halt(); } /* initialize free storage */ freeline = NULL; freedna = NULL; readnumber = true; /* usually we read in numbers for items */ number = 0; /* arbitrary value */ numbered = false; /* the piece has no number (none yet read in) */ skipunnum = false; } /* brinit */ /* end module book.brinit version = 'delmod 6.54 86 nov 12 tds/gds' */ /* ************************************************************************ */ /* end module package.brpiece version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.getpiece */ Static Void getpiece(thefile, pie) _TEXT *thefile; piece **pie; { /* move to and read in the next piece in the book */ Char ch; long SET[5]; ch = getto(thefile, P_addset(P_expset(SET, 0L), 'p')); /* get to the next p(iece) in the book */ if (ch != ' ') { brpiece(thefile, pie); ch = getto(thefile, P_addset(P_expset(SET, 0L), 'p')); /* read past closing p */ } } /* end module book.getpiece version = 'delmod 6.54 86 nov 12 tds/gds' */ /* ************************************************************************ */ /* end module package.getpiece version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module book.getbase */ Static base getbase(position, pie) long position; piece *pie; { /* get a base from the nth position (internal coordinates) of the piece. no protection is made against positions outside the piece */ dnastring *workdna; long p = dnamax; /* the last base of the dna part */ workdna = pie->dna; while (position > p) { p += dnamax; workdna = workdna->next; } return ((base)P_getbits_UB(workdna->part, position - p + dnamax - 1, 1, 3)); } /* end module book.getbase version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module basepair */ Static boolean basepair(xseq, yseq, x, y, guallowed) piece *xseq, *yseq; long x, y; boolean guallowed; { /* does xseq basepair to yseq at x to y? allow gu pair if guallowed is true. a series of if-then statements are used for speed. */ base bx, by; /* bases in the sequences */ bx = getbase(x, xseq); by = getbase(y, yseq); if (bx == complement(by)) return true; else if (guallowed) { if (bx == g && by == t) return true; else if (bx == t && by == g) return true; else return false; } else return false; } /* end module basepair version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module copyaline */ Static Void copyaline(fin, fout) _TEXT *fin, *fout; { /* copy a line from file fin to file fout */ while (!P_eoln(fin->f)) { putc(P_peek(fin->f), fout->f); getc(fin->f); } fscanf(fin->f, "%*[^\n]"); getc(fin->f); putc('\n', fout->f); } /* copyaline */ /* end module copyaline version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module unlimitln */ Static Void unlimitln(afile) _TEXT *afile; { /* this procedure removes a stupid system dependent limit on the number of lines that one can write to a file. you may remove it from the code if your system does not want or need this. suggested method: place comments around the contents of the procedure. */ /* linelimit(afile, maxint); (@ set 'infinite' lines allowed for afile */ } /* Local variables for numberdigit: */ struct LOC_numberdigit { long number, place; /* the exponent of logplace */ long absolute; /* the absolute value of number */ Char acharacter; /* the character to be returned */ } ; Local Void digit(LINK) struct LOC_numberdigit *LINK; { /* extract a digit at the place position */ long tenplace; /* ten times place */ long z; /* an intermediate value */ long d; /* the digit extracted */ tenplace = LINK->place * 10; z = LINK->absolute - LINK->absolute / tenplace * tenplace; if (LINK->place == 1) d = z; else d = z / LINK->place; switch (d) { case 0: LINK->acharacter = '0'; break; case 1: LINK->acharacter = '1'; break; case 2: LINK->acharacter = '2'; break; case 3: LINK->acharacter = '3'; break; case 4: LINK->acharacter = '4'; break; case 5: LINK->acharacter = '5'; break; case 6: LINK->acharacter = '6'; break; case 7: LINK->acharacter = '7'; break; case 8: LINK->acharacter = '8'; break; case 9: LINK->acharacter = '9'; break; } } /* digit */ Local Void sign(LINK) struct LOC_numberdigit *LINK; { /* put a negative sign out or a positive sign */ if (LINK->number < 0) LINK->acharacter = '-'; else LINK->acharacter = '+'; } /* sign */ /* end module unlimitln version = 'delmod 6.54 86 nov 12 tds/gds' */ /* begin module package.numbar */ /* ************************************************************************ */ /* begin module numberdigit */ Static Char numberdigit(number_, logplace) long number_, logplace; { /* return the digit at the place value ('logplace') position of number. example: numberdigit(13625, 3) = 3 numberdigit(13625, 4) = 1 */ struct LOC_numberdigit V; long count; /* used to make place */ V.number = number_; V.place = 1; for (count = 1; count <= logplace; count++) V.place *= 10; if (V.number == 0) { if (V.place == 1) V.acharacter = '0'; else V.acharacter = ' '; return V.acharacter; } V.absolute = labs(V.number); if (V.absolute < V.place / 10) { V.acharacter = ' '; return V.acharacter; } if (V.absolute >= V.place) digit(&V); else sign(&V); return V.acharacter; } /* numberdigit */ #define ln10 2.30259 /* natural log of 10 - for conversion to log base 10 */ #define epsilon 0.00001 /* a small number to correct log base 10 errors */ /* end module numberdigit version = 'prgmod 3.96 85 mar 18 tds'; */ /* begin module numbersize */ Static long numbersize(n) long n; { /* calculate amount of space to be reserved for the integer n */ if (n == 0) return 1; else { return ((long)(log((double)labs(n)) / ln10 + epsilon) + 2); /* the epsilon assures that we do not lose a place due to roundoff. eg, sometimes log base 10 of 10 would be 0.9999 instead of 1, and we would not do it right... note: this will fail for very large numbers on the order of 1/epsilon. */ /* the 2 is for the sign and last digit */ } } /* numbersize */ #undef ln10 #undef epsilon /* end module numbersize version = 'prgmod 3.96 85 mar 18 tds'; */ /* begin module numberbar */ Static Void numberbar(afile, spaces, firstnumber, lastnumber, linesused) _TEXT *afile; long spaces, firstnumber, lastnumber, *linesused; { /* write a bar of numbers to a file, with several spaces before. the number of lines used is returned */ long logplace; /* the log of the digit being looked at */ long spacecount; /* count of spaces */ long number; /* the current number being written */ if (labs(firstnumber) > labs(lastnumber)) *linesused = numbersize(firstnumber); else *linesused = numbersize(lastnumber); for (logplace = *linesused - 1; logplace >= 0; logplace--) { for (spacecount = 1; spacecount <= spaces; spacecount++) putc(' ', afile->f); for (number = firstnumber; number <= lastnumber; number++) fputc(numberdigit(number, logplace), afile->f); putc('\n', afile->f); } } /* end module numberbar version = 'prgmod 3.96 85 mar 18 tds'; */ /* ************************************************************************ */ /* end module package.numbar version = 'prgmod 3.96 85 mar 18 tds'; */ Static Void initialize() { /* set up all the variables */ printf(" dotmat %4.2f\n", version); brinit(&xbook); brinit(&ybook); if (*mlist.name != '\0') { if (mlist.f != NULL) mlist.f = freopen(mlist.name, "w", mlist.f); else mlist.f = fopen(mlist.name, "w"); } else { if (mlist.f != NULL) rewind(mlist.f); else mlist.f = tmpfile(); } if (mlist.f == NULL) _EscIO2(FileNotFound, mlist.name); SETUPBUF(mlist.f, Char); unlimitln(&mlist); xseq = (piece *)Malloc(sizeof(piece)); yseq = (piece *)Malloc(sizeof(piece)); /* read parameters */ if (*dotmatp.name != '\0') { if (dotmatp.f != NULL) dotmatp.f = freopen(dotmatp.name, "r", dotmatp.f); else dotmatp.f = fopen(dotmatp.name, "r"); } else rewind(dotmatp.f); if (dotmatp.f == NULL) _EscIO2(FileNotFound, dotmatp.name); RESETBUF(dotmatp.f, Char); if (BUFEOF(dotmatp.f)) guallowed = false; else if (P_peek(dotmatp.f) == 'g') guallowed = true; else guallowed = false; /* put header in mlist */ fprintf(mlist.f, " dotmat %4.2f from:\n", version); putc(' ', mlist.f); copyaline(&xbook, &mlist); putc(' ', mlist.f); copyaline(&ybook, &mlist); fprintf(mlist.f, "\n gu pairs are"); if (!guallowed) fprintf(mlist.f, " not"); fprintf(mlist.f, " allowed.\n\n"); fprintf(mlist.f, " symbols used:\n"); fprintf(mlist.f, " %c no complementary bases between these points\n", nodot); fprintf(mlist.f, " 1 gt base pair\n"); fprintf(mlist.f, " 2 at base pair\n"); fprintf(mlist.f, " 3 gc base pair\n"); } /****************************************************************************/ /* begin module dotmat.piecebar */ Static Void piecebar(afile, spaces, pie, firstnumber, lastnumber, linesused) _TEXT *afile; long spaces; piece *pie; long firstnumber, lastnumber, *linesused; { /* write a bar of numbers of the piece pie to a file, with several spaces before. the number of lines used is returned. based on procedure numbar. external procedures required: inttopie numbersize numberdigit */ long logpower; /* the log of the digit being looked at */ long spacecount; /* count of spaces */ long number; /* the current number being written */ struct { FILE *f; FILEBUFNC(f,long); Char name[_FNSIZE]; } numbers; /* a file for storing all the piece numbers */ long width; /* the lines used by one number */ long index; /* to pie */ *numbers.name = '\0'; /* calculate lines used and fill up the numbers file */ *linesused = 0; if (*numbers.name != '\0') numbers.f = fopen(numbers.name, "wb"); else numbers.f = tmpfile(); if (numbers.f == NULL) _EscIO2(FileNotFound, numbers.name); SETUPBUF(numbers.f, long); for (index = firstnumber; index <= lastnumber; index++) { number = inttopie(index, pie); fwrite(&number, sizeof(long), 1, numbers.f); width = numbersize(number); if (width > *linesused) *linesused = width; } for (logpower = *linesused - 1; logpower >= 0; logpower--) { for (spacecount = 1; spacecount <= spaces; spacecount++) putc(' ', afile->f); if (*numbers.name != '\0') numbers.f = freopen(numbers.name, "rb", numbers.f); else rewind(numbers.f); if (numbers.f == NULL) _EscIO2(FileNotFound, numbers.name); RESETBUF(numbers.f, long); while (!BUFEOF(numbers.f)) { fread(&number, sizeof(long), 1, numbers.f); fputc(numberdigit(number, logpower), afile->f); } putc('\n', afile->f); } fclose(numbers.f); } /* end module dotmat.piecebar */ /* begin module dotmat.makedna */ Static Void makedna(afile, spaces, pie, firstnumber, lastnumber) _TEXT *afile; long spaces; piece *pie; long firstnumber, lastnumber; { /* write a line of dna to a file, preceeded by several spaces */ long spacecount; /* count spaces */ long index; /* to pie */ for (spacecount = 1; spacecount <= spaces - 3; spacecount++) putc(' ', afile->f); fprintf(afile->f, "5%c ", prime); for (index = firstnumber; index <= lastnumber; index++) fputc(basetochar(getbase(index, pie)), afile->f); fprintf(afile->f, " 3%c\n", prime); } /* end module dotmat.makedna */ /* begin module dotmat.makepageheader */ Static Void makepageheader(pageheader) _TEXT *pageheader; { long lines; /* dummy until lines are counted by matrix */ if (*pageheader->name != '\0') { if (pageheader->f != NULL) pageheader->f = freopen(pageheader->name, "w", pageheader->f); else pageheader->f = fopen(pageheader->name, "w"); } else { if (pageheader->f != NULL) rewind(pageheader->f); else pageheader->f = tmpfile(); } if (pageheader->f == NULL) _EscIO2(FileNotFound, pageheader->name); SETUPBUF(pageheader->f, Char); fprintf(pageheader->f, "\f"); fprintf(pageheader->f, " matrix, x down: %ld %.*s y across: %ld %.*s\n\n", xnumber, namelength, xseq->key.hea.keynam.letters, ynumber, namelength, yseq->key.hea.keynam.letters); piecebar(pageheader, 10L, yseq, 1L, ylength, &lines); makedna(pageheader, 10L, yseq, 1L, ylength); fprintf(pageheader->f, " 5%c\n", prime); /* 8 spaces */ } /* end module dotmat.makepageheader */ /* begin module dotmat.printpageheader */ Static Void printpageheader(pageheader) _TEXT *pageheader; { /* print the page header */ if (*pageheader->name != '\0') { if (pageheader->f != NULL) pageheader->f = freopen(pageheader->name, "r", pageheader->f); else pageheader->f = fopen(pageheader->name, "r"); } else rewind(pageheader->f); if (pageheader->f == NULL) _EscIO2(FileNotFound, pageheader->name); RESETBUF(pageheader->f, Char); while (!BUFEOF(pageheader->f)) { while (!P_eoln(pageheader->f)) { putc(P_peek(pageheader->f), mlist.f); getc(pageheader->f); } fscanf(pageheader->f, "%*[^\n]"); getc(pageheader->f); putc('\n', mlist.f); } } /* end module dotmat.printpageheader */ Static Void printarray() { /* print array */ /* print out the array to mlist */ _TEXT pageheader; /* the header for pages of mlist */ long x, y; /* a point in the matrix */ base bx, by; /* bases at x and y of xseq and yseq respecitvely */ long FORLIM, FORLIM1; pageheader.f = NULL; *pageheader.name = '\0'; makepageheader(&pageheader); FORLIM = xlength; for (x = 1; x <= FORLIM; x++) { if (x % pagelength == 0 || x == 1) { /* p2c: dotmat.p, line 1055: * Note: Using % for possibly-negative arguments [317] */ printpageheader(&pageheader); } bx = getbase(x, xseq); fprintf(mlist.f, " %6ld %c ", inttopie(x, xseq), basetochar(bx)); FORLIM1 = ylength; for (y = 1; y <= FORLIM1; y++) { if (basepair(xseq, yseq, x, y, guallowed)) { /* make a number at the place */ by = getbase(y, yseq); if (bx == complement(by)) { switch (bx) { case a: putc('2', mlist.f); break; case c: putc('3', mlist.f); break; case g: putc('3', mlist.f); break; case t: putc('2', mlist.f); break; } } else putc('1', mlist.f); /* for gu pairs */ } else putc(nodot, mlist.f); } putc('\n', mlist.f); } fprintf(mlist.f, " 3%c\n", prime); /* 8 spaces */ if (pageheader.f != NULL) fclose(pageheader.f); } Static Void printdotmat() { /* print the dotmat for xseq and yseq */ printarray(); } main(argc, argv) int argc; Char *argv[]; { PASCAL_MAIN(argc, argv); if (setjmp(_JL1)) goto _L1; dotmatp.f = NULL; strcpy(dotmatp.name, "dotmatp"); mlist.f = NULL; strcpy(mlist.name, "mlist"); ybook.f = NULL; strcpy(ybook.name, "ybook"); xbook.f = NULL; strcpy(xbook.name, "xbook"); initialize(); while (!BUFEOF(xbook.f)) { getpiece(&xbook, &xseq); xnumber = number; xlength = piecelength(xseq); if (BUFEOF(xbook.f)) break; if (*ybook.name != '\0') { if (ybook.f != NULL) ybook.f = freopen(ybook.name, "r", ybook.f); else ybook.f = fopen(ybook.name, "r"); } else rewind(ybook.f); if (ybook.f == NULL) _EscIO2(FileNotFound, ybook.name); RESETBUF(ybook.f, Char); while (!BUFEOF(ybook.f)) { getpiece(&ybook, &yseq); ynumber = number; ylength = piecelength(yseq); if (BUFEOF(ybook.f)) break; printdotmat(); clearpiece(&yseq); } clearpiece(&xseq); } _L1: if (xbook.f != NULL) fclose(xbook.f); if (ybook.f != NULL) fclose(ybook.f); if (mlist.f != NULL) fclose(mlist.f); if (dotmatp.f != NULL) fclose(dotmatp.f); exit(EXIT_SUCCESS); } /* dotmat */ /* End. */