[From Bill Powers (990408.0253 MDT)]
Bruce Abbott (990407.1335 EST)]
Attached is my modification of your CUMREC.PAS, called CUMREC3P.PAS. I have
picked out two significant ways of presenting the data. One is a plot of
average interpress time versus time after food delivery. The other is a
histogram of number of presses per 1/30 sec bin as a function of time after
a food delivery.
The first one shows, I believe, the interval between presses as the delay
to the next food delivery (after the last one) gets longer. The average is
the appropriate measure because there are fewer long delays to the next
food delivery than there are short delays. What this graph shows is that
the rats begin delaying longer when the next food delivery doesn't show up
for a minute or two. I would interpret these long interpress times as time
spent away from the lever, rather than the rat standing in place with one
foot poised over it.
The second plot shows a histogram of number of responses in 1/30 sec bins
versus time since the previous food delivery. We get two distinctly
different plots for the two rats.
For 97002, there is a single peak at about 0.133 sec after food delivery,
showing an average rate of pressing of about 7.5 presses per second (if
I've figured that out right). This peak does not shift appreciably across
runs 145, 148, 149, and 150, the four I have (I trust that Bruce will copy
the data files to anyone who requests them). In this rat, an adequate model
would be one that presses steadily at a mean rate of 7.5 presses per second
with some statistical scatter about this mean, pausing only to collect the
food. The collection time varies with the amount of food being obtained,
from about 2 to 4 sec, with the fastest time occurring when the rat is
getting the least food. The only effect of the schedule is on collection time.
The other rat, 97001, shows similar effects except that there is a
pronounced second peak spanning 0.2 to 0.3 seconds delay, the amplitude of
which varies with the schedule. I would guess that this second peak
represents some idiosyncratic way of pressing the bar -- perhaps pawing at
it first with one forepaw (the first peak), then the other (which I have
seen in videos of rats pressing bars). A video would help. This second peak
stays at about the same delay across schedules, but the number of presses
at this delay changes with the schedule, the first peak rising and falling
the opposite way.
For both rats, I take the peak at 0.133 seconds to be caused by an
"overrun" -- the rats can't stop their repetitive pressing instantly when
the food appears, so there's always one extra press at the mean interpress
time later.
The peaks are spread out by (1) the fact that the apparatus enables the
reward trigger independently of the rat's lever presses, so that the press
that releases the food might occur at any time between one microsecond
after the trigger is enabled to one mean interpress time later, and (2) any
natural variation in the rats' mean rate of pressing. To test this model we
would need to generate artificial presses with an adjustable mean rate, and
an adjustable distribution, and run them through the same schedules. I
suspect that the pressing-rate distribution can be rather narrow, with most
of the scatter being provided by the variability in the interval schedule.
As a first approximation we could set the collection time to 3 seconds and
see how the histogram looks.
There is certainly a collection-time effect in these data, and very little
effect of schedule on rate of pressing, if any. Or so it appears now.
When you get back from the meeting, I hope we can work on refining this
preliminary interpretation of the data.
Best,
Bill P.
program CumRec3p;
{ Plots a cumulative record based on data files created by the FRATIO
and RANDOMVI real-time experiment programs.
Created 1/2/98 by B. Abbott
More plots added by WTP
}
uses dos, crt, frdata, graph, grutils;
const MAXDATA = 4500;
var
ch: char;
Filename, Path: pathstr;
bin: array[0..MAXDATA] of integer;
irtavg: array[0..MAXDATA] of longint;
nirt: array[0..MAXDATA] of longint;
R, P: dataptr;
RTon, RToff, PTon, PToff, Event: timesptr;
i, j, nR, nP: word;
NWords, SubjYr, SubjNo, Year, Month, Day, Session, Ratio,
Hour, Minute, Resp, Rft: word;
procedure InitScreen;
begin
initgraphics;
graphmode := getmaxmode;
setgraphmode(graphmode);
hsize := getmaxx + 1;
vsize := getmaxy + 1;
hcenter := hsize div 2;
vcenter := vsize div 2;
end;
procedure WriteData(nD: word; On, Off: timesptr);
var
i: word;
begin
writeln(nD:10);
for i := 1 to nD do
begin
write(On^[i]:8, Off^[i]:8);
if (i Mod 4 = 0) then writeln;
end;
writeln('Successfully wrote ', nD, ' values');
end;
function IRT(i: word; On, Off: timesptr): longint;
begin
if i = 1 then IRT := On^[i] else IRT := On^[i] - On^[i-1];
end;
function DUR(i: word; On, Off: timesptr): longint;
begin
DUR := Off^[i] - On^[i];
end;
procedure PlotlogIRT;
var
i, j, x, y,color: word;
yr: real;
istr: string;
begin
str(Session, istr);
outtextxy(10,35, 'Sess = '+istr);
str(nR, istr);
outtextxy(10,50, 'Rsp = '+istr);
str(nP, istr);
outtextxy(10,65, 'Rft = '+istr);
y := Vsize;
j := 1;
for i := 1 to nR do
begin
y := vsize - round(50.0*ln(IRT(i,RTon,RToff)));
x := (RTon^[i] * Hsize) div 72000;
putpixel(x,y, white);
end;
j := 1;
for i := 0 to 8
do
begin
if i > 0 then j := j + j;
y := j;
str(y/30:4:3,istr);
yr := ln(j);
outtextxy(hsize - 100,vsize - 8 - round(50*yr),istr);
end;
outtextxy(hsize - 100, 100, 'IRT, sec');
outtextxy(vcenter,0,'LOG IRT VERSUS TIME');
end;
procedure IRTHisto;
var basetime,maxtime: longint;
x,y,i,j,k: integer;
begin
clearviewport;
basetime := RTon^[1];
maxtime := 0;
j := 1;
for i := 0 to 3000 do bin[i] := 0;
for i := 1 to nR do
begin
if RTon^[i] >= PTon^[j] then
begin
inc(j);
basetime := RTon^[i];
end;
k := IRT(i,RTon,RToff);
inc(bin[k]);
if maxtime < k then maxtime := k;
end;
clearviewport;
setcolor(darkgray);
for i := 1 to 30 do
line(round(100*ln(i)),vsize,round(100*ln(i)),vsize - 360);
setcolor(white);
for i := 1 to 320 do
begin
y := bin[i];
if i = 1 then moveto(round(100*ln(i)),vsize - y)
else
lineto(round(100*ln(i)),vsize - y);
end;
setcolor(white);
line(0,vsize - 100,360,vsize - 100);
line(0,vsize - 200,360,vsize - 200);
line(0,vsize - 300,360,vsize - 300);
outtextxy(370,vsize - 100,'100');
outtextxy(370,vsize - 200,'200 PRESSES');
outtextxy(370,vsize - 300,'300');
outtextxy(0,vsize - 370,'0.033');
outtextxy(round(100*ln(3)) - 11,vsize-370,'0.1');
outtextxy(round(100*ln(6)) - 11,vsize-370,'0.2');
outtextxy(round(100*ln(9)) - 11,vsize-370,'0.3');
outtextxy(round(100*ln(15)) - 11,vsize-370,'0.5');
outtextxy(round(100*ln(30)) - 11,vsize-370,'1.0');
outtextxy(360,vsize - 370,'sec');
outtextxy(100, 0,' HISTOGRAM');
outtextxy(100,20,'IRT, 1/30 SEC INTERVALS AFTER RFT');
outtextxy(100,40,' LOG TIME SCALE');
outtextxy(100,60,filename);
end;
procedure IRTTime;
var basetime,maxtime: longint;
x,y,i,j,k,m,maxm: word;
avgrate: real;
firstp: boolean;
begin
basetime := RTon^[1];
maxtime := 0;
maxm := 0;
firstp := false;
j := 1;
for i := 0 to MAXDATA do irtavg[i] := 0;
for i := 0 to MAXDATA do nirt[i] := 0;
for i := 1 to nR - 1 do
begin
if RTon^[i] >= PTon^[j] then
begin
inc(j);
basetime := RTon^[i];
if not firstp then firstp := true;
end;
if firstp then
begin
{Fill in all histogram slots during IRT}
for m := RTon^[i] - basetime to RTon^[i+1] - basetime - 1 do
begin
if m > 2999 then continue;
irtavg[m] := irtavg[m] + RTon^[i+1] - RTon^[i];
inc(nirt[m]);
end;
if maxtime < (RTon^[i] - basetime)
then maxtime := (RTon^[i] - basetime);
end;
end;
for i := 1 to maxtime do
if nirt[i] > 0 then
irtavg[i] := round(irtavg[i]/nirt[i]);
for i := 1 to maxtime div 5 do
begin
if nirt[5*i] > 0 then
begin
if i = 1 then moveto(i,vsize - irtavg[5*i] div 4)
else lineto(i,vsize - irtavg[5*i] div 4);
end;
putpixel(i,vsize-1,white);
if (i mod 30) = 0 then line(i,vsize,i,vsize - 10);
end;
outtextxy(2*hsize div 3, vsize - 20,'10 second marks');
end;
procedure PlotIRTs;
var
i, j, x, y: word;
mark: boolean;
istr: string;
begin
outtextxy(hcenter-80, 10, 'IRT vs Response Count');
outtextxy(hcenter-75, 25, 'red = post reinf IRT');
str(Session, istr);
outtextxy(10,35, 'Sess = '+istr);
str(nR, istr);
outtextxy(10,50, 'Rsp = '+istr);
str(nP, istr);
outtextxy(10,65, 'Rft = '+istr);
outtextxy(hcenter-30, vsize-80, 'Time');
line(0, vsize-99, hsize, vsize-99);
line(0, vsize-400, 0, vsize-100);
for i := 0 to 300 do
if (i mod 30 = 0) then line(0,vsize-100-i, 6, vsize-100-i);
j := 1;
mark := false;
for i := 1 to nR do
begin
x := (RTon^[i] * Hsize) div 72000;
y := vsize - 100 - (IRT(i, RTon, RToff) div 1);
if (mark and (IRT(i, RTon, RToff) > 60)) then
begin
setcolor(lightred);
circle(x,y,3);
{ putpixel(x, y, lightred );}
mark := false;
end else putpixel(x, y, white);
if RTon^[i] = PTon^[j] then
begin
inc(j);
mark := true;
end;
end;
end;
procedure PlotIt; { cum record }
var
i, j, x, y: word;
istr: string;
begin
str(Session, istr);
outtextxy(10,35, 'Sess = '+istr);
str(nR, istr);
outtextxy(10,50, 'Rsp = '+istr);
str(nP, istr);
outtextxy(10,65, 'Rft = '+istr);
y := Vsize;
j := 1;
for i := 1 to nR do
begin
dec(y); if y = 0 then y := Vsize;
x := (RTon^[i] * Hsize) div 72000;
putpixel(x,y, white);
if RTon^[i] = PTon^[j] then
begin
inc(j);
line(x,y, x+5,y+5);
end;
end;
end;
begin
ClrScr;
Path := 'd:\tp\ratexp\vidata\';
Filename := '97002.145';
Filename := Path + Filename;
if FileExists(Filename) then
begin
InitScreen;
new(R); new(P);
new(RTon); new(RToff);
new(PTon); new(PToff);
writeln('Reading File ', Filename, ' . . .');
ReadData(Filename, SubjYr, SubjNo, Session,
Ratio, Year, Month, Day, Hour, Minute, Nwords,
Resp, Rft, R, P);
writeln('Decoding data . . .');
Decode(R, Nwords, RTon, RToff, nR);
Decode(P, Nwords, PTon, PToff, nP);
IRTTime;
ch := readkey;
IRThisto;
ch := readkey;
dispose(PToff); dispose(PTon);
dispose(RToff); dispose(RTon);
dispose(P); dispose(R);
CloseGraph;
end
else
begin
write('File Not Found . . .');
ch := readkey;
end;
end.