/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "curvafea.p" */ #include /* curvafea: DNA curvature to lister features Dr. Thomas D. Schneider National Cancer Institute Laboratory of Experimental and Computational Biology Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.lecb.ncifcrf.gov/~toms/ */ /* end of program */ /* begin module version */ #define version 1.06 /* of curvafea.p 2003 Sep 2 2003 Sep 2, 1.06: reduce output 2003 Aug 31, 1.05: accept blank and * lines in curvaout 2003 Aug 27, 1.04: sequence orientation bug 2003 Aug 26, 1.03: functinal 2003 Aug 26, 1.02: create curvaxyin 2003 Aug 26, 1.01: functional display of curvature on lister map! 2003 Aug 25, 1.00: origin from live.p 1.53 */ #define updateversion 1.00 /* defines lowest acceptable current parameter file */ /* end module version */ /* begin module describe.curvafea */ /* name curvafea: DNA curvature to lister features synopsis curvafea(book: in, curvafeap: in, curvaout: in, curvafeamarks: out, curvaxyin: out, output: out) files book: A book from the delila system. curvafeap: parameters to control the program. The file must contain the following parameters, one per line: 1. The version number of the program. This allows the user to be warned if an old parameter file is used. 2. zerobase: character and one integer OR one integer. The coordinate to set the phase of the wave by. This base will be red. If the first character is 'f' then the first base is the zerobase. If the first character is 'l' then the last base is the zerobase. When the first character is 'f' or 'l', it is followed by the zerobase as an offset. So f 0 is the first base, f 1 is the second base, etc. If the first character is not 'f' or 'l' then an integer is given that is the phase offset. When a set of coordinates are used (6th parameter and beyond), 'f' and 'l' apply to each coordinate pair. As a result, the phases of the colors WILL NOT MATCH. If neither 'f' nor 'l' are used, then there is only one zero base for all pairs, so THE PHASES WILL MATCH. 3. wavelength: one real. The wave length in bases. Usually there are 10.6 base pairs per turn of DNA, but using 10.0 allows checking the program. It can have other useful value, for example, one can set it to 3 to see translation frames. 4. wavevertical (real): how much to move the colored bar up or down (in character heights = bits). This is preadjusted (by a constant (shiftdown) to fit just between the lister map numbering and the sequence. 5. waveheight (real): the height of the colored bar (in character heights = bits). 0.25 is the normal value that fits the line between the lister map numbering and the sequence. 6. and all following lines: firstbase lastbase: two integers per line. The first and last bases to create marks for. There may be an indefinite number of lines. You can also use the program with different parameters and concatenate the curvafeamarks files together. WARNING: Coordinate systems can jump in the Delila system, so this method will fail across jumps. You can set the ranges by hand. This method can be used to mark only portions of the sequence. The program bookends can be used to find the end numbers of book pieces. IF PARAMETERs 6 ARE MISSING then the book will be used to obtain the coordinate system. This method should always work, but it gives curvafea marks for the entire book. curvaout: One or more '.map' files from the curva program. These give the coordinate followed by the curvature on each line. To make it possible to concatenate .map files together with spacers, blank lines and '*' at the starts of line are accepted (the latter as comments). curvafeamarks: marks for the lister program curvaxyin: curve in xyin format for the xyplo program output: messages to the user description The program makes waves for lister by using the marks definition. The waves are colored strips on the number line (or wherever the lister line starts). The strip shows the phase of the DNA, allowing the orientation of binding sites to be compared. Since lister marks must be in order of the coordinate system, integrating the curvafea marks with other marks would require a lot of hand editing. The mergemarks program allows marks to be smoothly joined together. examples 1.34 version of curvafea that this parameter file is designed for. f 0 zerobase: to set the phase of the wave by. This base will be red. 10.6 wavelength: The wave length in bases. Usually 10.6. 0 wavevertical: amount to shift colored wave vertically 0.25 waveheight: height of colored wave Optionally, there can be: -150 92 firstbase lastbase: range of sequence to mark ... (any number of repeats of the last line above may be made) documentation The CURVATURE (ie curva) program is described at: @article{Shpigelman.Bolshoy1993, author = "E. S. Shpigelman and E. N. Trifonov and A. Bolshoy", title = "{CURVATURE: software for the analysis of curved DNA}", journal = "Comput Appl Biosci", volume = "9", pages = "435--440", year = "1993"} see also {example parameter file:} curvafeap {The curves program is available from:} http://ext.haifa.ac.il/~leokol/curvature/ {A script that takes a book as input and uses this program to generate various files that can be used with Delila programs is:} run.curva {the program that uses the curvafeamarks:} lister.p {another program that could use curvafea marks:} makelogo.p {a program to merge curvafeamarks with others: } mergemarks.p {a program to obtain the range of a book: } bookends.p {a program for plotting the curvaxyin: } xyplo.p {Documentation on how the curvafea program produces the color wave:} http://www-lecb.ncifcrf.gov/~toms/livecolors/ {This program was created by modifying: } live.p author Thomas Dana Schneider bugs NOTES from live.p: When one gives a pair of coordinates, curvafea creates marks running between the pair. This will *fail* when there is a coordinate jump. Also, it means that if the coordinate system is decreasing, the wave colors will be *reversed*. When the book is used for coordinates, the wave is determined on internal (1 to n) coordinates and so the colors will never be reversed. It is not clear yet whether the latter solution is a problem or not. (Is it a bug or a feature? :-) Are there times when one would like the colors to reverse when the piece reverses? The answer to the above is YES: the colors must reverse for curva! zzz check that this is true The code could be imbedded into lister. technical notes The definition of the marks is in makelogo.p More information about the colors is in xyplo.p */ /* end module describe.curvafea */ /* begin module curvafea.const */ #define shiftdown (-0.350) /* amount to shift the strip down, so that it fits nicely between the numbering and DNA. */ #define saturation 0.5 /* how saturated the colors are */ /* end module curvafea.const */ /* begin module book.const */ /* constants needed for book manipulations */ #define dnamax 1024 /* length of dna arrays */ #define namelength 100 /* maximum key name length */ #define linelength 80 /* maximum line readable in book */ /* end module book.const version = 7.56; {of delmod.p 2000 Nov 21} */ /* 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; /* begin module base.type */ /* define the four nucleotide bases */ typedef enum { a, c, g, t } base; /* end module base.type version = 7.56; {of delmod.p 2000 Nov 21} */ /* sequence types */ typedef short dnarange; /* p2c: curvafea.p, line 259: * 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 = 7.56; {of delmod.p 2000 Nov 21} */ typedef struct parameters { /* parameters to control the program */ double parameterversion; /* parameter version number */ long firstbase; /* first base to mark */ long lastbase; /* last base to mark */ long zerobase; /* the base to be 'red' */ double wavelength; /* wave length in bases */ double wavevertical; /* wave vertical shift in bits */ double waveheight; /* height of the bar in bits */ Char basephase; /* phase starts on the first (f) or last (l) base, ' ' means specified zero */ } parameters; Static _TEXT book; /* file used by this program */ Static _TEXT curvafeap; /* file used by this program */ Static _TEXT curvaout; /* file used by this program */ Static _TEXT curvafeamarks; /* file used by this program */ /* file used by this program */ Static _TEXT curvaxyin; /* file used by this program */ /* 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 = 7.56; {of delmod.p 2000 Nov 21} */ /* 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 = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module package.getocp */ /* ************************************************************************ */ /* 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 writeline(afile, l, carriagereturn) _TEXT *afile; line *l; boolean carriagereturn; { /* write a line to a file, with carriage return if carriagereturn is true. */ long index; /* index to characters in l */ long FORLIM; FORLIM = l->length; for (index = 0; index < FORLIM; index++) putc(l->letters[index], afile->f); if (carriagereturn) putc('\n', afile->f); } Static Void showfreedna() { /* show the freedna list */ long counter = 0; /* count of freedna list */ dnastring *l; /* pointer into freedna list */ l = freedna; while (l != NULL) { counter++; printf("%ld", counter); printf(", length = %d\n", l->length); /* This is illegal according to gpc because one cannot write a pointer to a text file. It can be unearthed for debugging. write(output, ', pointer id: ',l:1); */ l = l->next; } } 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 Char chomplement(b) Char b; { /* create the character complement of base b. I must be getting hungry! */ return (basetochar(complement(chartobase(b)))); } 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 = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.getto */ Static Char getto(thefile, theline, ch) _TEXT *thefile; long *theline; long *ch; { /* search the file for a character in the first line which is a member of the set ch. Note: on 1999 March 10 the definition of this function was cleaned up. Instead of putting thefile on the line AFTER the charcter ch has been found, it puts thefile ON the line. Other routines like brdna and brpiece have to move to the next line themselves. This makes getto give the OBJECT. */ Char achar = ' '; /* a character in thefile */ boolean done = false; /* done finding achar */ while (!done) { if (BUFEOF(thefile->f)) { done = true; break; } achar = P_peek(thefile->f); if (P_inset(achar, ch)) { done = true; break; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; } if (P_inset(achar, ch)) return achar; else { return ' '; /* The old method - while (not(achar in ch)) and (not eof(thefile)) do begin readln(thefile,achar); theline := succ(theline) end; if (achar in ch) then getto:=achar else getto:=' ' */ } } /* end module book.getto version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.skipstar */ Static Void skipstar(thefile) _TEXT *thefile; { /* skip start of line (or star = '*'). */ if (BUFEOF(thefile->f)) { printf(" procedure skipstar: end of book found\n"); halt(); return; } 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 = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brreanum */ Static Void brreanum(thefile, theline, reanum) _TEXT *thefile; long *theline; double *reanum; { /* read a real number from the file */ skipstar(thefile); fscanf(thefile->f, "%lg%*[^\n]", reanum); getc(thefile->f); (*theline)++; } /* end module book.brreanum version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brnumber */ Static Void brnumber(thefile, theline, num) _TEXT *thefile; long *theline, *num; { /* read a number from the file */ skipstar(thefile); fscanf(thefile->f, "%ld%*[^\n]", num); getc(thefile->f); (*theline)++; } /* end module book.brnumber version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brname */ Static Void brname(thefile, theline, nam) _TEXT *thefile; long *theline; 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); (*theline)++; } /* brname */ /* end module book.brname version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brline */ Static Void brline(thefile, theline, l) _TEXT *thefile; long *theline; line **l; { /* read a line from the file */ long i = 0; Char acharacter; skipstar(thefile); while (!P_eoln(thefile->f)) { i++; acharacter = getc(thefile->f); if (acharacter == '\n') acharacter = ' '; (*l)->letters[i-1] = acharacter; } (*l)->length = i; (*l)->next = NULL; fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; } /* end module book.brline version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brdirect */ Static Void brdirect(thefile, theline, direct) _TEXT *thefile; long *theline; direction *direct; { /* read a direction */ Char ch; skipstar(thefile); fscanf(thefile->f, "%c%*[^\n]", &ch); getc(thefile->f); if (ch == '\n') ch = ' '; (*theline)++; if (ch == '+') *direct = plus; else *direct = minus; } /* end module book.brdirect version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brconfig */ Static Void brconfig(thefile, theline, config) _TEXT *thefile; long *theline; configuration *config; { /* read a configuration */ Char ch; skipstar(thefile); fscanf(thefile->f, "%c%*[^\n]", &ch); getc(thefile->f); if (ch == '\n') ch = ' '; (*theline)++; if (ch == 'l') *config = linear; else *config = circular; } /* end module book.brconfig version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brnotenumber */ Static Void brnotenumber(thefile, theline, note) _TEXT *thefile; long *theline; 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); (*theline)++; if (P_peek(thefile->f) != 'n') { 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); (*theline)++; } while (P_peek(thefile->f) != 'n'); fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; return; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; } /* brnotenumber */ /* end module book.brnotenumber version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brnote */ Static Void brnote(thefile, theline, note) _TEXT *thefile; long *theline; 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); (*theline)++; if (P_peek(thefile->f) != 'n') { /* abort null note (n/n) */ getline(note); newnote = *note; while (P_peek(thefile->f) != 'n') { /* wait until end of note */ brline(thefile, theline, &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); (*theline)++; return; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; } /* brnote */ /* end module book.brnote version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brheader */ Static Void brheader(thefile, theline, hea) _TEXT *thefile; long *theline; header *hea; { /* read the header of a key. */ fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* move past the object name - new definition 1999 Mar 13 */ (*theline)++; /*bbb*/ /* read key name */ brname(thefile, theline, &hea->keynam); /* read full name */ getline(&hea->fulnam); brline(thefile, theline, &hea->fulnam); /* read note key */ if (readnumber) brnotenumber(thefile, theline, &hea->note); else brnote(thefile, theline, &hea->note); } /* end module book.brheader version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.copyheader */ Static Void copyheader(fromhea, tohea) header fromhea, *tohea; { /* copy the header fromhea into tohea. Note that the linked objects are NOT copied, but merely pointed to. */ memcpy(tohea->keynam.letters, fromhea.keynam.letters, sizeof(alpha)); tohea->keynam.length = fromhea.keynam.length; tohea->note = fromhea.note; tohea->fulnam = fromhea.fulnam; } /* end module book.copyheader version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brpiekey */ Static Void brpiekey(thefile, theline, pie) _TEXT *thefile; long *theline; piekey *pie; { /* read piece key, track the line number */ brheader(thefile, theline, &pie->hea); brreanum(thefile, theline, &pie->mapbeg); brconfig(thefile, theline, &pie->coocon); brdirect(thefile, theline, &pie->coodir); brnumber(thefile, theline, &pie->coobeg); brnumber(thefile, theline, &pie->cooend); brconfig(thefile, theline, &pie->piecon); brdirect(thefile, theline, &pie->piedir); brnumber(thefile, theline, &pie->piebeg); brnumber(thefile, theline, &pie->pieend); } /* end module book.brpiekey version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brdna */ Static Void brdna(thefile, theline, dna) _TEXT *thefile; long *theline; dnastring **dna; { /* read in dna from thefile, track the line */ /* 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, theline, P_addset(P_expset(SET, 0L), 'd')); fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); (*theline)++; 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 */ (*theline)++; ch = getc(thefile->f); /* ch is either '*' or 'd' */ if (ch == '\n') ch = ' '; } fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* read past the d */ (*theline)++; } /* end module book.brdna version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brpiece */ Static Void brpiece(thefile, theline, pie) _TEXT *thefile; long *theline; piece **pie; { /* read in a piece, change theline to reflect the lines traversed */ /* readln(thefile); (* move past the word 'piece' - new definition 1999 Mar 13 *) theline := succ(theline); (* BUG: was below! *) bbb*/ brpiekey(thefile, theline, &(*pie)->key); if (numbered || !skipunnum) brdna(thefile, theline, &(*pie)->dna); fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* move past the word 'piece' - new definition 1999 Mar 13 */ (*theline)++; } /* end module book.brpiece version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brinit */ Static Void brinit(book, theline) _TEXT *book; long *theline; { /* 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; *theline = 1; } /* brinit */ /* end module book.brinit version = 7.56; {of delmod.p 2000 Nov 21} */ /* ************************************************************************ */ /* end module package.brpiece version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brorgkey */ Static Void brorgkey(thefile, theline, org) _TEXT *thefile; long *theline; orgkey *org; { /* read organism key */ /*bbb*/ brheader(thefile, theline, &org->hea); getline(&org->mapunit); brline(thefile, theline, &org->mapunit); } /* end module book.brorgkey version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.brchrkey */ Static Void brchrkey(thefile, theline, chr) _TEXT *thefile; long *theline; chrkey *chr; { /* read chromosome key */ /*bbb*/ brheader(thefile, theline, &chr->hea); brreanum(thefile, theline, &chr->mapbeg); brreanum(thefile, theline, &chr->mapend); } /* end module book.brchrkey version = 7.56; {of delmod.p 2000 Nov 21} */ /* begin module book.getocp */ Static Void getocp(thefile, theline, org, orgchange, orgopen, chr, chrchange, chropen, pie, piechange, pieopen) _TEXT *thefile; long *theline; orgkey *org; boolean *orgchange, *orgopen; chrkey *chr; boolean *chrchange, *chropen; piece **pie; boolean *piechange, *pieopen; { /* Get the next piece and its organism and chromosome keys. The three change variables indicate whether or not a new organism, chromosome or piece name was found. If a piece is not found, then pieopen will be false. orgopen, chropen and pieopen are used by getocp to tell when it has entered an organism, chromosome or piece. All booleans should be set to false initially. There should be one triplet for each book read. It is important to initialize ALL variables, including pie: orgchange := false; orgopen := false; chrchange := false; chropen := false; piechange := false; pieopen := false; pie := nil; 1999 June 2 The book reading routines now treat data objects more precisely. Rather than test for eof, the endo of book occurs when pieopen is returned as false. A book reading loop now looks like this: repeat getocp(book, theline, org, orgchange, orgopen, chr, chrchange, chropen, pie, piechange, pieopen); writeln(output,'pieopen: ',pieopen); until not pieopen; */ Char ch = 'a'; chrkey newchr; orgkey neworg; piece *newpie; long SET[5]; while (ch != 'p' && ch != ' ') { P_addset(P_expset(SET, 0L), 'o'); P_addset(SET, 'c'); ch = getto(thefile, theline, P_addset(SET, 'p')); if (ch == ' ') { *pieopen = false; break; } switch (ch) { case 'o': if (*orgopen) { fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* move past the word 'organism' - new definition 1999 Mar 13 */ *orgopen = false; /* close organism */ } else { brorgkey(thefile, theline, &neworg); if (strncmp(neworg.hea.keynam.letters, org->hea.keynam.letters, sizeof(alpha)) && neworg.hea.keynam.length != org->hea.keynam.length) { /* writeln(output,'--------orgchanged!'); write (output,'--------old org:"', org.hea.keynam.letters); writeln(output, '" ', org.hea.keynam.length:1); write (output,'--------new org:"',neworg.hea.keynam.letters); writeln(output, '" ',neworg.hea.keynam.length:1); */ /*ccc*/ *orgchange = true; copyheader(neworg.hea, &org->hea); } else *orgchange = false; *orgopen = true; } break; case 'c': if (*chropen) { fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); /* move past the word 'chromosome' - new definition 1999 Mar 13 */ *chropen = false; /* close chromosome */ } else { brchrkey(thefile, theline, &newchr); if (strncmp(newchr.hea.keynam.letters, chr->hea.keynam.letters, sizeof(alpha)) && newchr.hea.keynam.length != chr->hea.keynam.length) { /* writeln(output,'--------chrchanged!'); write (output,'--------old chr:"', chr.hea.keynam.letters); writeln(output, '" ', chr.hea.keynam.length:1); write (output,'--------new chr:"',newchr.hea.keynam.letters); writeln(output, '" ',newchr.hea.keynam.length:1); */ *chrchange = true; copyheader(newchr.hea, &chr->hea); } else *chrchange = false; *chropen = true; } break; case 'p': if (*pieopen) { *pieopen = false; /* close last piece */ ch = 'a'; /* prevent falling out of the loop */ } else { newpie = (piece *)Malloc(sizeof(piece)); brpiece(thefile, theline, &newpie); if (*pie == NULL) *piechange = true; else { if (strncmp(newpie->key.hea.keynam.letters, (*pie)->key.hea.keynam.letters, sizeof(alpha)) && newpie->key.hea.keynam.length != (*pie)->key.hea.keynam.length) *piechange = true; else *piechange = false; } *pieopen = true; /* we always have to switch over to the new piece, because although the name may be the same, the DNA sequence could be different. That is, the book may contain two pieces with the same name, and we want to be sure to search the new one, not the old one. */ if (*pie != NULL) { clearpiece(pie); /* save the links */ Free(*pie); /* close up shop */ } *pie = newpie; } break; } } } /* end module book.getocp version = 7.56; {of delmod.p 2000 Nov 21} */ /* ************************************************************************ */ /* end module package.getocp version = 7.56; {of delmod.p 2000 Nov 21} */ Static Void readparameters(curvafeap, p) _TEXT *curvafeap; parameters *p; { /* read the parameters p from curvafeap */ if (*curvafeap->name != '\0') { if (curvafeap->f != NULL) curvafeap->f = freopen(curvafeap->name, "r", curvafeap->f); else curvafeap->f = fopen(curvafeap->name, "r"); } else rewind(curvafeap->f); if (curvafeap->f == NULL) _EscIO2(FileNotFound, curvafeap->name); RESETBUF(curvafeap->f, Char); fscanf(curvafeap->f, "%lg%*[^\n]", &p->parameterversion); getc(curvafeap->f); if (p->parameterversion < updateversion) { printf("You have an old parameter file!\n"); halt(); } if ((P_peek(curvafeap->f) == 'f') | (P_peek(curvafeap->f) == 'l')) { fscanf(curvafeap->f, "%c%ld%*[^\n]", &p->basephase, &p->zerobase); getc(curvafeap->f); if (p->basephase == '\n') p->basephase = ' '; } else { p->basephase = ' '; fscanf(curvafeap->f, "%ld%*[^\n]", &p->zerobase); getc(curvafeap->f); } fscanf(curvafeap->f, "%lg%*[^\n]", &p->wavelength); getc(curvafeap->f); fscanf(curvafeap->f, "%lg%*[^\n]", &p->wavevertical); getc(curvafeap->f); fscanf(curvafeap->f, "%lg%*[^\n]", &p->waveheight); getc(curvafeap->f); /* the remainder of the parameters are read later: */ /* readln(curvafeap,firstbase, lastbase); */ /* checks */ if (p->wavelength <= 0) { printf("wavelength must be positive\n"); halt(); } if (p->waveheight <= 0) { printf("waveheight must be positive\n"); halt(); } } #define wid 10 /* width for putting numbers */ #define dec 5 /* decimal for putting numbers */ Static Void writeparameters(f, p) _TEXT *f; parameters *p; { /* read the parameters p from curvafeap */ fprintf(f->f, "* %*.2f parameterverion\n", wid, p->parameterversion); fprintf(f->f, "* %*ld firstbase\n", wid, p->firstbase); fprintf(f->f, "* %*ld lastbase\n", wid, p->lastbase); /* writeln(output,'basephase =',basephase); */ switch (p->basephase) { case 'f': fprintf(f->f, "* first base + %*ld is zerobase\n", wid, p->zerobase); break; case 'l': fprintf(f->f, "* last base + %*ld is zerobase\n", wid, p->zerobase); break; case ' ': fprintf(f->f, "* %*ld zerobase\n", wid, p->zerobase); break; } fprintf(f->f, "* %*.*f wavelength\n", wid, dec, p->wavelength); fprintf(f->f, "* %*.*f wavevertical\n", wid, dec, p->wavevertical); fprintf(f->f, "* %*.*f waveheight\n", wid, dec, p->waveheight); } #undef wid #undef dec Static Void makecurvafeamarks(curvaout, f, p) _TEXT *curvaout, *f; parameters p; { /* using the curve data in curvaout, make curvafea marks into file f*/ if (*f->name != '\0') { if (f->f != NULL) f->f = freopen(f->name, "w", f->f); else f->f = fopen(f->name, "w"); } else { if (f->f != NULL) rewind(f->f); else f->f = tmpfile(); } if (f->f == NULL) _EscIO2(FileNotFound, f->name); SETUPBUF(f->f, Char); fprintf(f->f, "* curvafea %4.2f, create curve features\n\n", version); writeparameters(f, &p); fprintf(f->f, "\nu\n"); /* user definitions */ fprintf(f->f, "%% fs is the font size vertically\n"); fprintf(f->f, "%% charwidth is assumed to exist (it does in makelogo and lister)\n"); fprintf(f->f, "%% as the width of the characters horizontally.\n"); fprintf(f->f, "%% define font size as a unit of measure:\n"); fprintf(f->f, "/fs {fontsize mul} def\n\n"); /* Definitions of marks according to makelogo: U Call the user defined symbol. The U must be followed by 4 coordinates numbers: x1 y1 x2 y2. The x1 and x2 are in bases, while y1 and y2 are in bits. The remainder of the line is copied to the logo file, so you can have more parameters there. End the line with the name of one of your defined symbols. * a comment line % a comment line If marksymbol is b, l or U, 4 more parameters are required: base coordinate: a real number that determines end 1 bits coordinate: a real number that determines end 1 base coordinate: a real number that determines end 2 bits coordinate: a real number that determines end 2 The line is drawn from end 1 to end 2 while these ends define box diagonal. Note that the center of a base is defined as an integer, so one must add 0.5 to base coordinates to put a boxes around a base. You may make the user symbol use these coordinates however you want. */ fprintf(f->f, "/wavebox { %% TailX TailY HeadX HeadY wbcolor wavebox -\n"); fprintf(f->f, "%% make a box for the wave n charcters vertically from zero\n"); fprintf(f->f, "/wbcolor exch def\n"); fprintf(f->f, "/HeadY exch def\n"); fprintf(f->f, "/HeadX exch def\n"); fprintf(f->f, "/TailY exch def\n"); fprintf(f->f, "/TailX exch def\n"); fprintf(f->f, "gsave\n"); fprintf(f->f, "%% shift left 1 character:\n"); fprintf(f->f, "charwidth neg 0 translate\n"); /* writeln(f,'charwidth neg wbcolor 0.5 sub cm translate'); for testing*/ fprintf(f->f, "TailX TailY moveto\n"); fprintf(f->f, "HeadX TailY lineto\n"); fprintf(f->f, "HeadX HeadY lineto\n"); fprintf(f->f, "TailX HeadY lineto\n"); fprintf(f->f, "TailX TailY lineto\n"); fprintf(f->f, "wbcolor %5.3f 1 sethsbcolor\n", saturation); fprintf(f->f, "fill\n"); fprintf(f->f, "grestore\n"); /* % TailX TailY HeadX HeadY Shift % bases bits bases bits bases */ fprintf(f->f, "} def\n"); fprintf(f->f, "!\n\n"); /* end of user definitions */ } Static Void markat(curvafeamarks, x, y, waveheight, color) _TEXT *curvafeamarks; double x, y, waveheight, color; { /* mark a box at base x and y characters vertically. The procedure is a wrapper to make generation easy. The lister program needs two user defined coordinates ("head" and "tail" of an arrow or corners of a rectangle). These are not convenient in this program. Here it is easier to think about the base location we want to box. */ /* writeln(curvafeamarks, '* TailX TailY HeadX HeadY color'); writeln(curvafeamarks, '* bases bits bases bits '); */ fprintf(curvafeamarks->f, "U %10.5f %10.5f %10.5f %10.5f %10.5f wavebox\n", x, y, x + 1, y + waveheight, color); } Static double setcolor(thezero, internal, wavelength, huge_) long thezero, internal; double wavelength; long huge_; { /* Set the color to cycle over the spectrum, using internal coordinates. thezero is where the base should be tagged red, internal is the base being worked on, wavelength is the wave length of the color cycle change. This is a particularly difficult routine because one needs to map the difference between internal and thezero into a number between 0 and 1. The hard part is that functions like trunc act *differently* on the two sides of the origin, which would make an unacceptable jump in the final color. Methods that try to account for the trunc function near zero tend to fail. The simplest solution is to get away from zero by adding a huge number, taking the trunc, and then subtracting away the huge number. This huge number doesn't really need to be very large, it only needs to be beyond the range of the coordinate system. */ double thecolor; /* color computed from position */ double x; /* the distance from the zero coordinate, in wavelengths */ double y; /* a number between 0 and 1, cycling according to x */ x = (internal - thezero) / wavelength; y = x + huge_ - (long)(x + huge_); thecolor = 0.85 * y; /* rescale to make spectrum */ return thecolor; /* write(output,'thezero = ',thezero:6:3,' '); write(output,'wavelength = ',wavelength:6:3,' '); */ /* write(output,'internal = ',internal:6:3,' '); write(output,'huge = ',huge:6:3,' '); writeln(output,'x = ',x:6:3, ', y=',y:6:3); */ /* write(output,'internal-thezero=',(internal-thezero):5); write(output,'thecolor = ',thecolor:5:3); write(output,', thezero = ',thezero:5); write(output,', internal = ',internal:5); writeln(output); */ } Static Void nobookloop(thezero, cooexternal, p, huge_) long thezero, cooexternal; parameters p; long huge_; { /* zero point */ /* external coordinate */ /* do the inner part of a loop */ double thecolor; /* color computed from position */ thecolor = setcolor(thezero, cooexternal, p.wavelength, huge_); /*writeln(output,'thecolor = ',thecolor:5:3);*/ markat(&curvafeamarks, (double)cooexternal, shiftdown + p.wavevertical, p.waveheight, thecolor); } #define wid 10 /* width of numerical output */ #define dec 5 /* decimals of numericaloutput */ #define saturation_ 1.0 /* color definition */ #define brightness 1.0 /* color definition */ Static Void bookloop(thezero, internal, pie, p, huge_, cinternal, curvaout, curvaxyin) long thezero, internal; piece *pie; parameters p; long huge_, *cinternal; _TEXT *curvaout, *curvaxyin; { /* zero point */ /* internal coordinate */ /* piece of DNA */ /* do the inner part of a loop, with zero base at thezero and internal as the *internal* coordinate. Read the curve data from curvaout. */ /* thezero: the computed zero base */ double hue; /* color computed from position */ double curvature; /* the curvature from curvaout */ long piecoordinate; /* piece coordinates */ long sign; /* orientation of the piece */ piekey *WITH; WITH = &pie->key; /* This is the part of the live.p program that is replaced: hue := setcolor(thezero, internal, wavelength, huge); */ /*writeln(output,'hue = ',hue:5:3);*/ if (WITH->piedir == WITH->coodir) sign = 1; else sign = -1; /* write(output, ' internal: ', internal:3); */ if (!((*cinternal <= internal) & (!BUFEOF(curvaout->f)))) return; if (*cinternal < internal) { if (P_eoln(curvaout->f)) { /* skip blank lines */ fscanf(curvaout->f, "%*[^\n]"); getc(curvaout->f); } else if (P_peek(curvaout->f) == '*') { /* skip comment lines */ fscanf(curvaout->f, "%*[^\n]"); getc(curvaout->f); } else { fscanf(curvaout->f, "%ld%lg%*[^\n]", cinternal, &curvature); getc(curvaout->f); } } /* use previous value */ /* write(output, ' cinternal: ', cinternal:3); write(output, ' curvature: ',curvature:5:3); */ /* writeln(curvaxyin, ' curvature: ',curvature:5:3); if internal > 15 then begin writeln(output); halt; end; */ if (internal != *cinternal) return; /* write(output, ' internal'); writeln(output); writeln(output,' HOLD ON NELLY'); halt; */ if (curvature <= 1) hue = 0.84 * curvature + 0.16; else hue = 1.0; /* safety feature */ piecoordinate = inttopie(internal, pie); /*inttopie(internal, pie),*/ markat(&curvafeamarks, (double)piecoordinate, shiftdown + p.wavevertical, p.waveheight, hue); fprintf(curvaxyin->f, "%*ld %*.*f %*.*f %*.*f %*.*f %*ld\n", wid, internal, wid, dec, curvature, wid, dec, hue, wid, dec, saturation_, wid, dec, brightness, wid, sign * piecoordinate); /*zzz here also write out the xyin data so it can be plotted on a logo ... oh! do like a sine wave?*/ /* write(output, ' -------'); */ /* writeln(output,' %'); */ } #undef wid #undef dec #undef saturation_ #undef brightness /* begin module curvafea.themain */ Static Void themain(book, curvafeap, curvaout, curvafeamarks, curvaxyin) _TEXT *book, *curvafeap, *curvaout, *curvafeamarks, *curvaxyin; { /* the main procedure of the program */ long internal; /* internal coordinate corresponding to l */ long inthezero; /* the computed zero base in internal coordinates */ long l; /* position on sequence */ parameters p; long thezero; /* the computed zero base in external coordinates */ long huge_; /* a large positive integer */ /* parameters for reading the book: */ long theline; orgkey org; boolean orgchange = false, orgopen = false; chrkey chr; boolean chrchange = false, chropen = false; piece *pie = NULL; boolean piechange = false, pieopen = false; long cinternal = 0; long FORLIM; /* the internal coordinate according to curvaout */ printf("curvafea %4.2f\n", version); readparameters(curvafeap, &p); makecurvafeamarks(curvaout, curvafeamarks, p); if (*curvaout->name != '\0') { if (curvaout->f != NULL) curvaout->f = freopen(curvaout->name, "r", curvaout->f); else curvaout->f = fopen(curvaout->name, "r"); } else rewind(curvaout->f); if (curvaout->f == NULL) _EscIO2(FileNotFound, curvaout->name); RESETBUF(curvaout->f, Char); if (*curvaxyin->name != '\0') { if (curvaxyin->f != NULL) curvaxyin->f = freopen(curvaxyin->name, "w", curvaxyin->f); else curvaxyin->f = fopen(curvaxyin->name, "w"); } else { if (curvaxyin->f != NULL) { rewind(curvaxyin->f); } else curvaxyin->f = tmpfile(); } if (curvaxyin->f == NULL) _EscIO2(FileNotFound, curvaxyin->name); SETUPBUF(curvaxyin->f, Char); fprintf(curvaxyin->f, "* curvafea %4.2f\n", version); fprintf(curvaxyin->f, "* columns:\n"); fprintf(curvaxyin->f, "* 1 internal coordinate\n"); fprintf(curvaxyin->f, "* 2 curvature units (relative to nucleosome bending)\n"); fprintf(curvaxyin->f, "* 3 hue for color\n"); fprintf(curvaxyin->f, "* 4 saturation for color\n"); fprintf(curvaxyin->f, "* 5 brightness for color\n"); fprintf(curvaxyin->f, "* 6 piecoordinate: coordinate on the book\n"); if (!BUFEOF(curvafeap->f)) { printf("Warning: not using book; coordinates may not be correct:\n"); printf("assuming 1 to n coordinates\n"); huge_ = (long)(LONG_MAX / 2.0); while (!BUFEOF(curvafeap->f)) { fscanf(curvafeap->f, "%ld%ld%*[^\n]", &p.firstbase, &p.lastbase); getc(curvafeap->f); switch (p.basephase) { case 'f': thezero = p.firstbase + p.zerobase; break; case 'l': thezero = p.firstbase + p.zerobase; break; case ' ': thezero = p.zerobase; break; } inthezero = thezero; /* assuming 1 to n coordinates */ if (p.firstbase <= p.lastbase) { for (l = p.firstbase; l <= p.lastbase; l++) nobookloop(inthezero, l, p, huge_); } else { for (l = p.firstbase; l >= p.lastbase; l--) nobookloop(inthezero, l, p, huge_); } } return; } /* read from the book */ brinit(book, &theline); do { getocp(book, &theline, &org, &orgchange, &orgopen, &chr, &chrchange, &chropen, &pie, &piechange, &pieopen); if (pieopen) { if (number > 1) fprintf(curvafeamarks->f, "p - curvafea skip to piece %ld\n\n", number); fprintf(curvafeamarks->f, "* piece %ld\n", number); /* writeln(output, zerobase:5,' is zerobase'); writeln(output, 'basephase = "',basephase,'"'); */ switch (p.basephase) { case 'f': thezero = pietoint(pie->key.piebeg, pie) + p.zerobase; /* this can't be right! double call to the pietoint! inthezero := pietoint(thezero, pie); */ inthezero = thezero; break; case 'l': thezero = pietoint(pie->key.pieend, pie) + p.zerobase; /* see above inthezero := pietoint(thezero, pie); */ inthezero = thezero; break; case ' ': thezero = p.zerobase; inthezero = thezero; break; } /* writeln(output, inthezero:5,' is inthezero'); */ huge_ = piecelength(pie) * 2; FORLIM = piecelength(pie); for (internal = 1; internal <= FORLIM; internal++) bookloop(inthezero, internal, pie, p, huge_, &cinternal, curvaout, curvaxyin); } } while (pieopen); } /* end module curvafea.themain */ main(argc, argv) int argc; Char *argv[]; { PASCAL_MAIN(argc, argv); if (setjmp(_JL1)) goto _L1; curvaxyin.f = NULL; strcpy(curvaxyin.name, "curvaxyin"); curvafeamarks.f = NULL; strcpy(curvafeamarks.name, "curvafeamarks"); curvaout.f = NULL; strcpy(curvaout.name, "curvaout"); curvafeap.f = NULL; strcpy(curvafeap.name, "curvafeap"); book.f = NULL; strcpy(book.name, "book"); themain(&book, &curvafeap, &curvaout, &curvafeamarks, &curvaxyin); _L1: if (book.f != NULL) fclose(book.f); if (curvafeap.f != NULL) fclose(curvafeap.f); if (curvaout.f != NULL) fclose(curvaout.f); if (curvafeamarks.f != NULL) fclose(curvafeamarks.f); if (curvaxyin.f != NULL) fclose(curvaxyin.f); exit(EXIT_SUCCESS); } /* End. */