home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oakland CPM Archive
/
oakcpm.iso
/
sigm
/
sigmv071.ark
/
STATISTI.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1984-04-29
|
15KB
|
739 lines
program xstat;{$P+}
{$c-,m-,f-}
label 1;
const
defaultpad =' ';
type
id = array[1..6] of char;
calendar = array [1..2] of char;
date_of_test = record
month:calendar;
day:calendar;
year:calendar
end;
lab_data = record
name: array [1..30] of char;
chart_number:id;
date: date_of_test;
sex:boolean;
weight: real;
height: real;
surface_area: real;
chronological_age: real;
bone_age: real;
height_age:real;
percent_overweight_for_height:real;
total_body_water: real;
values:array[1..18,1..14] of real;
pad:array[1..59] of char;
end;
xstatistical = array[1..20,1..14,1..18] of real;
byte = 0..255;
$string0 = string 0;
$string255 = string 255;
$string80 = string 80;
$string14 = string 14;
$string4 = string 4;
f = file of lab_data;
axis_label = array[1..4] of char;
var
filename:$string14;
norms,data:lab_data;
num_values, peak_time,time,results,x,y,i:byte;
fin:f;
average,max,min,sum:real;
hardcopy,normal_value_flag, error, terminate, continue,escape:boolean;
rec:integer;
strvalue:$string80;
x_axis_label,y_axis_label: array[1..14] of axis_label;
statistics:xstatistical;
output:text;
{************************* init labels for axis *************************}
procedure initialize;
var
i:byte;
begin
x_axis_label[1]:= '-30 ';
x_axis_label[2]:= '-1 ';
x_axis_label[3]:= '15 ';
x_axis_label[4]:= '30 ';
x_axis_label[5]:= '45 ';
x_axis_label[6]:= '60 ';
x_axis_label[7]:= '90 ';
x_axis_label[8]:= '120 ';
x_axis_label[9]:= '150 ';
x_axis_label[10]:= '180 ';
x_axis_label[11]:= '210 ';
x_axis_label[12]:= '240 ';
x_axis_label[13]:= '300 ';
x_axis_label[14]:= '360 ';
y_axis_label[1]:= 'BS ';
y_axis_label[2]:= 'IRI ';
y_axis_label[3]:= 'GH ';
y_axis_label[4]:= 'LH ';
y_axis_label[5]:= 'FSH ';
y_axis_label[6]:= 'F ';
y_axis_label[7]:= 'PRL ';
y_axis_label[8]:= 'TSH ';
y_axis_label[9]:= 'T ';
y_axis_label[10]:= 'DS ';
y_axis_label[11]:= 'ACTH';
y_axis_label[12]:= 'T4 ';
y_axis_label[13]:= 'TBG ';
y_axis_label[14]:= 'TT3 ';
end;
procedure setlength (var x:$string0; y:integer);external;
function length (x:$string255):integer; external;
procedure keyin(var cix:char);external;
procedure clear_screen;
begin
write (chr(27),'*',chr(0),chr(0),chr(0),chr(0));
end;
procedure erase_lines(starting_line,number_of_lines:byte);
const
blanks = ' ';
var
i:byte;
begin
for i:= 1 to number_of_lines do
begin
write(chr(27),'=',chr(starting_line + 31),chr(32),blanks,blanks);
starting_line:= starting_line + 1;
end;
end;
procedure move_cursor(x,y:byte);
begin
write(chr(27),'=',chr(y+31),chr(x+31));
end;
procedure prompt (x,y,length:byte; p:$string80;
protected_field_desired:boolean);
var
underline:string 80;
i:byte;
begin
setlength(underline,0);
for i:= 1 to length do append (underline,'_');
if protected_field_desired = false then
write(chr(27),'=',chr(y+31),chr(x+31),p,underline)
else
write(chr(27),'=',chr(y+31),chr(x+31),chr(27),')',p,
underline,chr(27),'(');
end;
function query(x,y:byte; message:$string80):boolean; {ask y/n question}
var
answer:char;
begin
repeat
move_cursor(x,y);
write(message);
keyin(answer);
until answer in ['y','n','Y','N'];
query:= ((answer = 'y') or (answer = 'Y'));
erase_lines(y,1);
end;
function number_records(filenam:$string14):integer;
label 1;
var
num:integer;
i:byte;
begin
num:= 0;
reset (filename,fin);
if eof(fin) then
begin
num:= 1;
goto 1;
end;
with data do
begin
read(fin:1,data);
for i:= 1 to 6 do num:= num*10 + ord(chart_number[i])-48;
end;
1: number_records:= num;
end;
procedure init_statistical_array;
begin
clear_screen;
writeln;
writeln('Initializing and loading values into matrix. One moment, please.');
for rec:= 1 to 20 do
for results:= 1 to 14 do
for time:= 1 to 18 do
statistics[rec,results,time]:= -999.0;
end;
procedure axis;
var
i:byte;
begin
writeln; {DEBUG delay...terminal does not seem to respond fast enough}
for i:= 6 to 19 do
begin
move_cursor(1,i-1);
write(x_axis_label[i-5]:4);
end;
move_cursor(9,4);
for i:= 1 to 14 do
write(y_axis_label[i]:4,' ');
end;
procedure display_values;
var
x,y,i:byte;
continue:char;
begin
clear_screen;
escape:=false;
with data do
begin
writeln(' '); {DEBUG for terminal delay}
axis;
move_cursor(1,1);
write('name: ',name:30,'chart #: ':10,data.chart_number:6,
'date: ':8,date.month:2,'/',date.day:2,'/',date.year:2);
if sex then writeln('sex: male') else writeln('sex: female');
write('ht: ',height:5:1,'wt: ':6,weight:5:1,
'S.A.:':5,surface_area:5:1);
writeln('% OWt: ':8,percent_overweight_for_height:5:1,
'T.B.W.: ':10,total_body_water:5:1);
writeln('age:':5,chronological_age:5:1,'B.A.: ':8,bone_age:5:1,
'H.A.: ':8,height_age:5:1);
x:= 7;
y:= 5;
for time:= 1 to 14 do
begin
for results:= 1 to 14 do
begin
move_cursor(x,y);
if abs(values[time,results]) <> 999.0 then
write(values[time,results]:4:1) else
write(' '); {4 spaces}
x:= x + 5;
end;
y:= y + 1;
x:= 7;
end;
end; {of with data}
end;
procedure values_calculation;
var
num:byte;
begin
with data do
begin
for results:= 1 to 14 do
begin
max:= values[1,results];
peak_time:= 1;
if values[1,results] = -999.0 then
begin
sum:= 0.0;
num_values:= 0;
min:=999.0;
end;
if values[1,results] > -999.0 then
begin
sum:= values[1,results] ;
num_values:= 1;
min:= values[1,results];
end;
for time := 2 to 14 do
begin
if max < values[time,results] then
begin
max:= values[time,results];
peak_time:= time;
end;
if (values[time,results] > -999.0) and (min > values[time,results])
then min:= values[time,results];
if values[time,results] > -999.0 then
begin
sum:= sum + values[time,results] ;
num_values:= num_values + 1;
end;
end;
average:= sum/num_values;
values[15,results]:= max;
values[16,results]:= min;
if average = 0.0 then values[17,results]:= -999.0 else
values[17,results]:= average;
case peak_time of
1: values[18,results]:= -30.0;
2: values[18,results]:= -1.0;
3: values[18,results]:= 15.0;
4: values[18,results]:= 30.0;
5: values[18,results]:= 45.0;
6: values[18,results]:= 60.0;
7: values[18,results]:= 90.0;
8: values[18,results]:= 120.0;
9: values[18,results]:= 150.0;
10: values[18,results]:= 180.0;
11: values[18,results]:= 210.0;
12: values[18,results]:= 240.0;
13: values[18,results]:= 300.0;
14: values[18,results]:= 360.0;
end;
if average = 0.0 then values[18,results]:= -999.0;
end;
end;
end;
procedure mistake;
label 1,2;
var
strtime,strtest:$string80;
xtime,xtest: axis_label;
matrix,i,ii,j,time,test:byte;
found,finished:boolean;
begin
finished:= false;
repeat
1: erase_lines(1,1);
move_cursor(1,1);
write('Enter test and time of incorrect data, e.g. BS <cr> 30 <cr> ');
move_cursor(65,1);
i:=0;
repeat
i:= i + 1;
keyin(xtest[i]);
write(xtest[i]);
until (xtest[i] = chr(13)) or (i = 4);
if xtest[i] = chr(13) then
for ii:= i to 4 do xtest[ii]:= ' ';
if xtest[1] = chr(27) then
begin
finished:= true;
goto 2;
end;
move_cursor(75,1);
i:= 0;
repeat
i:= i + 1;
keyin(xtime[i]);
write(xtime[i]);
until (xtime[i] = chr(13)) or (i = 4);
if xtime[i] = chr(13) then
for ii:= i to 4 do xtime[ii]:= ' ';
erase_lines(1,1);
time:= 255;
test:= 255;
matrix:= 1;
found:= false;
repeat
if xtime = x_axis_label[matrix] then
begin
found:= true;
time:= matrix;
end;
matrix:= matrix + 1;
until (found) or (matrix > 14);
matrix:= 1;
found:= false;
repeat
if xtest = y_axis_label[matrix] then
begin
found:= true;
test:= matrix;
end;
matrix:= matrix + 1;
until (found) or (matrix > 14);
if time = 255 then
begin
erase_lines(1,1);
move_cursor(1,1);
write('You have entered an invalid time, please reenter test & time: ');
goto 1;
end;
if test = 255 then
begin
erase_lines(1,1);
move_cursor(1,1);
write('You have entered an invalid test, please reenter test & time: ');
goto 1;
end;
prompt(test*5+4,time+2,0,'omit',false);
data.values[time,test]:= -999.0;
2: until finished;
erase_lines(1,1);
values_calculation;
end;
procedure choose_and_exclude_test;
var
test:char;
begin
clear_screen;
writeln;
writeln('A- BLOOD SUGAR');
writeln('B- INSULIN');
writeln('C- GROWTH HORMONE');
writeln('D- LH');
writeln('E- FSH');
writeln('F- CORTISOL');
writeln('G- PROLACTIN');
writeln('H- TSH');
writeln('I- TESTOSTERONE');
writeln('J- DS');
writeln('K- ACTH');
writeln('L- T4');
writeln('M- TBGI');
writeln('N- TT3');
writeln('O- finished excluding tests');
writeln;
write('Please enter the letter corresponding to the test: ');
repeat
repeat
move_cursor(61,19);
keyin(test);
if (ord(test) > 96) and (ord(test) < 123) then
test:= chr(ord(test)-32);
write(test);
until test in ['A'..'O'];
results:= ord(test)-64;
if results < 15 then
begin
writeln;
write('Values for ',y_axis_label[results],' will be ignored during analysis.');
for time:= 1 to 18 do
data.values[time,results]:= -999.0
end;
until results = 15;
end;
procedure offer_hardcopy;
var
ch:char;
begin
clear_screen;
repeat
move_cursor(1,5);
write('Do you want a hardcopy of the data? y/n ');
keyin(ch);
until ch in ['y','n','Y','N'];
if ch in ['y','Y'] then hardcopy:= true else hardcopy:= false;
clear_screen;
if hardcopy = false then rewrite('con:',output) else
begin
rewrite('lst:',output);
writeln('Prepare printer, then enter any character to initiate printing.');
keyin(ch);
end;
end;
procedure load_statistical_array;
label 1;
var
continue:char;
last_record:integer;
exclude:boolean;
procedure select_data;
label 1;
var
exclusion:char;
begin
display_values;
move_cursor(1,19);
writeln('Considering this patient''s lab results, choose one: ');
writeln('1- Accept all data as displayed for statistical analysis.');
writeln('2- Exclude all values for 1 or more test(s) from analysis.');
writeln('3- Exclude only one or more value(s) from statistical analysis.');
writeln('4- Exclude patient''s entire lab values from analysis.');
repeat
move_cursor(55,19);
keyin(exclusion);
until exclusion in ['0'..'4'];
erase_lines(19,5);
exclude:=false;
case exclusion of
'1': goto 1;
'2': choose_and_exclude_test;
'3': mistake;
'4': exclude:= true;
end;
1:
end; {of procedure}
procedure print_raw_data;
var
stop,start:integer;
i:byte;
ch:char;
begin
for results:= 1 to 14 do
begin
start:= 2;
repeat
if (start + 7) > last_record then stop:= last_record else
stop:= start + 7;
if hardcopy then write(output,chr(12)) else
begin
erase_lines(1,1);
move_cursor(1,1);
write('Enter any character to continue. ');
keyin(ch);
clear_screen;
end;
for i:= 1 to 3 do writeln(output);
writeln(output,'RAW DATA FOR TEST :',y_axis_label[results]:4);
writeln(output);
write(output,' ');
for i:= start to stop do write(output,'#':5,i:2);
writeln(output);
for time:= 1 to 18 do
begin
if time < 15 then write(output,x_axis_label[time]:4) else
case time of
15: write(output,'max ');
16: write(output,'min ');
17: write(output,'ave ');
18: write(output,'peak');
end;
for rec:= start to stop do
if abs(statistics[rec,results,time]) <> 999.0 then
write(output,statistics[rec,results,time]:7:1) else
write(output,' ':7);
writeln(output);
end;
start:= start + 8;
until start > last_record;
end;
end;
begin
reset(filename,fin);
if eof(fin) then
begin
clear_screen;
writeln('FILE NOT FOUND!');
writeln;
writeln('Enter any character to continue. ');
keyin(continue);
goto 1;
end;
last_record:= number_records(filename);
with data do
begin
for rec:= 2 to last_record do
begin
read(fin:rec,data);
select_data;
for results:= 1 to 14 do
for time:= 1 to 18 do
if exclude = true then statistics[rec,results,time]:=-999.0
else statistics[rec,results,time]:= values[time,results];
end;
offer_hardcopy;
print_raw_data;
end;
1:
end; {of procedure}
procedure stat_average;
var
standard_deviation,max,min,average,sum:real;
last_record,counter:integer;
i:byte;
ch:char;
procedure calc_variance;
var
i:byte;
variance,xvariance:real;
begin
xvariance:=0.0;
for i:= 2 to last_record do
if abs(statistics[i,results,time]) <> 999.0 then
xvariance:=xvariance + sqr(statistics[i,results,time]-average);
variance:=xvariance/(counter-1);
standard_deviation:= sqrt(variance);
end;
begin
clear_screen;
offer_hardcopy;
last_record:= number_records(filename);
writeln;
if hardcopy then writeln('Now printing.');
for results:= 1 to 14 do
begin
if hardcopy then write(output,chr(12)) else
begin
erase_lines(1,1);
move_cursor(1,1);
write('Enter any character to continue. ');
keyin(ch);
clear_screen;
end;
for i:= 1 to 3 do writeln(output);
writeln(output,'STATISTICAL ANALYSIS FOR TEST : ',y_axis_label[results]);
writeln(output);
writeln(output,'ave':9,'n':5,'s.d.':7,'max':6,'min':7);
writeln(output);
for time:= 1 to 18 do
begin
sum:= 0.0;
counter:= 0;
max:= statistics[1,results,1];
if statistics[1,results,1] = -999.0 then
min:= 999.0 else min:= statistics[1,results,1];
if time < 15 then write(output,x_axis_label[time]:4) else
case time of
15: write(output,'max ');
16: write(output,'min ');
17: write(output,'ave ');
18: write(output,'peak');
end;
for rec:= 2 to last_record do
begin
if abs(statistics[rec,results,time]) <> 999.0 then
begin
sum:= sum + statistics[rec,results,time];
counter:= counter + 1;
if statistics[rec,results,time] > max then
max:= statistics[rec,results,time];
if statistics[rec,results,time] < min then
min:= statistics[rec,results,time];
end;
end;
average:= sum/counter;
if (average = 0.0) or (abs(average) = 999.0) then
write(output,' ':18) else
begin
calc_variance;
write(output,average:7:1);
write(output,counter:4,standard_deviation:7:1);
end;
if abs(max) <> 999.0 then write(output,max:7:1) else
write(output,' ':7);
if abs(min) <> 999.0 then write(output,min:7:1) else
write(output,' ':7);
writeln(output);
if hardcopy then writeln(output);
end;
end;
end;
procedure get_filename;
var
newfile:boolean;
begin
clear_screen;
writeln;
writeln('Enter name of patient data file as: drive:name.extension ');
writeln;
writeln('Drive is either ''A'' or ''B'' .');
writeln('Name may be up to 14 letters. ');
writeln('Extention may be up to 3 letters.');
move_cursor(10,10);
write('----> ');
read(filename);
reset(filename,fin);
if eof(fin) then
begin
prompt(10,15,0,'A file by that name is NOT FOUND. ',false);
newfile:= query(10,16,'Is this a new file? y/n');
if newfile then rewrite(filename,fin) else get_filename;
end;
end;
{*************************** main program *******************************}
begin
get_filename;
initialize;
init_statistical_array;
load_statistical_array;
stat_average;
end.