There are a couple of minor issues in the way that you measure the scene duration.
In the scene framework, all stimuli (visual, auditory, TTL, etc.) start at the first frame of the current scene and end at the first frame of the next scene. In the following code, for example, it seems that you think CS is off at 104, but that is not the case. The stimuli turned on at 103 are turned off at 105, so the timestamp of 104 does not mean anything.
run_scene(scene2,103); % CS On
eventmarker(104); % CS Off
run_scene(scene3,105); % Trace Interval
It is hardly necessary to call extra eventmarker() in the scene framework, unless the eventcode itself, not its timestamp, has some meaning to you.
You are printing something on the MATLAB command window with disp(). It used to be a source of huge delay, so I recommend you not to do so. Use dashboard(), instead, if you want to display something during the trial.
Your frame interval is too long. Since your refresh rate is ~60Hz, the interval should be 16-17 ms. I cannot tell whether it is because your computer is slow or the task is too complex.
Nevertheless, those things cannot explain the interval 200 ms shorter than the specified duration nor the session-by-session variability. I suggest running a simple code to verify the problem. Something like this.
bhv_code(10,'Event 10',20,'Event 20');
idle(100);
tc = TimeCounter(null_);
tc.Duration = 1500;
scene = create_scene(tc);
run_scene(scene,10);
idle(100,[],20);
The interval between 10 and 20 should be 1500 ms or one frame longer. If you still see an interval shorter than that, please send me the data file.
-----
I guess it is possible that your computer might calculate the refresh rate incorrectly. That can explain the session-by-session variability, but NIMH ML does not use the calculated refresh rate, if the system reports the rate as a fraction. What is your NIMH ML version? Please update it if it is not up to date.