I hope people will forgive the use of bandwidth, it's pretty short...
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 at ncifcrf.gov
National Cancer Institute
Laboratory of Mathematical Biology
1994
*)
label 1; (* end of program *)
const
(* begin module version *)
version = 1.08; (* of asciidna.p 1994 January 27
origin 1994 January 27 *)
(* end module version *)
(* begin module describe.asciidna *)
(*
name
asciidna: draw ASCII DNA
synopsis
asciidna(asciidnap: in, plot: in, 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 at 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.