program asciidna(asciidnap, plot, output); (* asciidna: draw ASCII DNA Tom Schneider NCI/FCRDC Bldg 469. Room 144 P.O. Box B Frederick, MD 21702-1201 (301) 846-5581 (-5532 for messages) network address: toms@ncifcrf.gov National Cancer Institute Laboratory of Mathematical Biology 1994 *) label 1; (* end of program *) const (* begin module version *) version = 1.09; (* of asciidna.p 1994 May 25 origin 1994 January 27 *) (* end module version *) (* begin module describe.asciidna *) (* name asciidna: draw ASCII DNA synopsis asciidna(asciidnap: in, plot: out, output: out) files asciidnap: parameters to control the program linewidth: integer, length in characters of the line to create wavelength: real, wavelength in characters amplitude: real, height of the waves incharacters phase1: real, phase shift in characters of first wave phase2: real, phase shift in characters of second wave Watson: character, the character for one strand Crick: character, the character for the other strand (that one's a REAL character!) barmajor: character, the character for the major groove barminor: character, the character for the minor groove bargap: integer, distance between bars in characters plot: plot of spiral dna output: messages to the user description The program draws a spiral DNA in ASCII characters. It was inspired by: // \\ // \\ // \\ // \\ // \\ // \\ // \\ Jim Sloan // | :,\\': | \\ // | :,\\': | \\ // | :,\\': | \\ jsloan@u.washington.edu \\ | | \\ // | | // \\ | | \\ // | | // \\ | | \\ | :,\\': | // \\ | :,\\': | // \\ | :,\\': | // \\ | \\ // \\ // \\ // \\ // \\ // \\ // \\ The Pascal code may be obtained by anonymous ftp from ncifcrf.gov in pub/delila/asciidna.p.Z and pub/delila/asciidnap. examples if asciidnap contains: *********************************************************** 80 linewidth: integer, length in characters of the line to create 24 wavelength: real, wavelength in characters 8 amplitude: real, height of the waves incharacters -1 phase1: real, phase shift in characters of first wave 4 phase2: real, phase shift in characters of second wave W watson: character, the character for one strand C crick: character, the character for the other strand | barmajor: character, the character for the major groove : barminor: character, the character for the minor groove 3 bargap: integer, distance between bars in characters asciidnap: parematers to control the asciidna program *********************************************************** one obtains: *********************************************************** asciidna 1.08 CCC WWW CCC WWW CCC WWW CC :CC| WW CC :CC| WW CC :CC| WW C : W C | W C : W C | W C : W C | W W C : W C | W C : W C | W C : W C | W |W C: :W C| |W C: :W C| |W C: :W C| |W | W C : W C | W C : W C | W C : W C | W C | W C : W C | W C : W C | W C : W C | W C C |WW: WW CC |WW: WW CC |WW: WW CC |WW: CCC WWW CCC WWW CCC WWW CCC WW *********************************************************** documentation see also dnag.p author Thomas Dana Schneider bugs technical notes *) (* end module describe.asciidna *) var asciidnap, plot: text; (* files used by this program *) (* begin module halt *) procedure 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. *) begin writeln(output,' program halt.'); goto 1 end; (* end module halt version = 'delmod 6.16 84 mar 12 tds/gds'; *) (* begin module asciidna.themain *) procedure themain(var asciidnap, plot: text); (* the main procedure of the program *) const pi = 3.1415926535; (* ratio of circle circumfrence to diameter *) xmax = 80; (* largest horizontal size *) ymax = 30; (* largest vertical size *) var amplitude: real; (* height of sinewave *) barmajor, barminor: char; (* characters to fill in major and minor grooves *) bargap: integer; (* distance between bars in characters *) field : array[0..xmax, 0..xmax] of char; (* a field of characters *) multiplier: real; (* pre calculated value for speed *) phase1: real; (* phase difference of first wave, characters *) phase2: real; (* phase difference of second wave, characters *) x: integer; (* x position *) y: integer; (* y position *) y1: integer; (* first wave y position *) y2: integer; (* second wave y position *) z1: integer; (* first wave y position in 3 space *) z2: integer; (* second wave y position in 3 space *) linewidth: integer; (* width of line on paper *) wavelength: real; (* characters per wavelength *) Watson, Crick: char; (* characters involved with DNA *) function outer(x: real): integer; (* outer part of the function *) begin outer := round(amplitude*(x+1)/2); end; function inner(x: integer; phase: real): real; (* inner part of the function *) begin inner := multiplier*(x+phase); end; begin writeln(output,'asciidna ',version:4:2); rewrite(plot); writeln(plot,' asciidna ',version:4:2); reset(asciidnap); readln(asciidnap, linewidth); readln(asciidnap, wavelength); readln(asciidnap, amplitude); readln(asciidnap, phase1); readln(asciidnap, phase2); readln(asciidnap, Watson); readln(asciidnap, Crick); readln(asciidnap, barmajor); readln(asciidnap, barminor); readln(asciidnap, bargap); if linewidth > xmax then begin writeln(output,'linewidth > ',xmax:1); halt; end; if amplitude > ymax then begin writeln(output,'amplitude > ',ymax:1); halt; end; multiplier := 2 * pi / wavelength; linewidth := linewidth - 1; (* redefine to save calculation *) for x := 0 to linewidth do for y := 0 to round(amplitude) do field[x,y] := ' '; for x := 0 to linewidth do begin (* the code does the following, but is implemented efficiently y1 := round(amplitude*(sin(multiplier*(x+phase1)) + 1)/2); y2 := round(amplitude*(sin(multiplier*(x+phase2)) + 1)/2); z1 := round(amplitude*(cos(multiplier*(x+phase1)) + 1)/2); z2 := round(amplitude*(cos(multiplier*(x+phase2)) + 1)/2); *) y1 := outer(sin(inner(x,phase1))); y2 := outer(sin(inner(x,phase2))); z1 := outer(cos(inner(x,phase1))); z2 := outer(cos(inner(x,phase2))); (* fill in bases *) if (x mod bargap) = 0 then begin if y1 < y2 then begin for y := y1 to y2 do field[x,y] := barmajor end else begin for y := y2 to y1 do field[x,y] := barminor end; end; (* do crossover here *) if z1 > z2 then begin field[x,y2] := Crick; field[x,y1] := Watson; end else begin field[x,y1] := Watson; field[x,y2] := Crick; end; end; (* plot the graph *) for y := 0 to round(amplitude) do begin for x := 0 to linewidth do write(plot,field[x,y]); writeln(plot); end; end; (* end module asciidna.themain *) begin themain(asciidnap, plot); 1: end.