function  [data,P] = PLExp2b(sbj_number,DB_spec)

%PLEXP2A -- Perceptual Learning Exp.2, PHASE 3 (mixed backgrounds)
%
%  [data,P] = PLExp2b(sbj_number,[DB_spec])
%
%  The input and output arguments are the same as in PLEXP2.
%  SBJ_NUMBER must specify an existing subject (see FIND_SBJ_DESCR). 
%  Phase 3 of the experiment comprises session 12. 
%  See PLEXP2A for the previous phase (sessions 10 and 11).
%  There is no demo session in this phase. Both kinds of backgrounds
%  appear in each block, in a counterbalanced design. No feedback.
%
%  DATA is a matrix with one row per trial and with 21 columns.
%  The exact data format is described in PLEXP2. All fields in phase 3
%  are the same but the values for the following fields are different:
%    7. noise orientation (1=L,-1=R,2=R,-2=R, where -X=flipLR(X))
%    8. actual noise orientation (-15 or +15 degrees)
%   11. Gabor orientation (1=L,-1=R,2=R,-2=R, where -X=flipLR(X))
%   12. actual Gabor orientation (-10 or +10 degrees)
%   19. correct (1 iff (((Gabor_orient>0)&(resp==Gabor_orient))  | ...
%                       ((Gabor_orient<0)&(resp==3+Gabor_orient))  ))
%  The data from phase 3 are appended to the end of the phase-1+2 file.
%
%  See also PLEXP2, PLEXP2A, IMPORT_PLE2_DATA, MAKE_PLE2_STIM.

%  Original coding by Alexander Petrov, UC Irvine.
%  $Revision: 1.0 $  $Date: 2003/09/08 10:30 $

global NOISE_CACHE

%-- Print herald
outs = 1 ;   % output stream = standard output
fprintf(outs,'\nPerceptual learning experiment, ver. 2, phase 3.\n') ;

%-- Set random generator seed
seed = round(100*sum(clock)) ;    % see RAND's help page
rand('state',seed) ;
fprintf(outs,'\nRandom generator seed set to %d.\n',seed) ;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%   ALL GLOBAL PARAMETERS ARE IN A SEPARATE FILE   %%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

P = PLExp2_params(1) ;   % <-- Very important file PLEXP2_PARAMS.M


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%      EXPERIMENTAL DESIGN      %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is 'phase 3' of the experiment. See PLEXP2 and PLEXP2A for the 
% first twi phases. Phase 3 begins after the participant has already 
% completed 11 days (or 'sessions') of training with homogenous blocks.
% In phase 3, both background orientations (or 'contexts') are mixed
% within each block. There are 4 blocks of 300+ trials each,1200+ total.
%
% The stimuli are Gabor patches embedded in noise. They are exactly the
% same as in phases 1 and 2 (see PLEXP2, PLEXP2A, and MAKE_PLE2_STIM).
% The NCache file loads noise patches of one orientation. The other
% is derived simply by flipping the image vertically (via FLIPLR).

schedule{1} = [1 1 1 1] ;          % half trials are flipped anyway
schedule{2} = 3 - schedule{1} ;    % counterbalance groups

% The instructions are identical to those in Phase 1 (see PLEXP2), as
% well as all other experimental details (durations, lack of feedback).
%
% The background-noise patches are generated in advance and written on
% a CD-ROM in "caches" of 300. Each cache is in a separate file with
% names such as L01_001.mat, R01_001.mat, L01_002.mat, ... R01_036.mat.
% The NC_fnumbers on day 12 are the same as those on day 6. Note that
% no cache files are actually reused because they have opposite orients.
% All NC indices are randomized from scratch during each block.
% 
% The stimuli vary along the following four dimensions in each block:
%  - Gabor orientation (with 2 levels: 1 and 2)
%  - Gabor peak contrast (with 3 levels, see P.Gabor_Cpeak below)
%  - presentation position on the screen (with 2 levels, see P.position)
%  - flipLR (with 2 levels: +1=dont_flip, -1=flip)
% Thus there are 24 different stimuli altogether. Each block contains
% 13 replications of each stimulus, making 312 trials total. The actual
% number of trials may be slightly greater than that because invalid
% trials (e.g. when the subject presses a bad key) are repeated.
% Note that there are slightly fewer trials (300/block) in phase 1.

levels = {[1 2],...     % indices in P.Gabor_orient, see DO_PLE2_TRIAL
          [1 2 3],...   % indices in P.Gabor_Cpeak , see MAKE_PLE2_STIM
          [1 2],...     % indices in P.position, see DO_PLE2_TRIAL
          [-1 +1] } ;   % whether to flipLR (-1) or not (+1)

%-- Session parameters
replications = 13 ;
trials_per_block = 24 * replications ;    % 2x3x2x2=24 stimuli


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%   EQUIPMENT CHARACTERISTICS   %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% NANAO Technology FlexScan 6600 paperwhite monitor with a P4 phosphor.
% Driven by the internal videocard of a Power Macintosh 7300/200.
% A special circuit combines two 8-bit output channels of the video-
% card to produce 24*256=6144 distinct gray levels (see MAKE_LINEAR_LUT).

whichScreen = 1 ;         % present stimuli on the auxiliary monitor
viewing_dist = P.viewing_dist ;   % 720 milimeters, +/-10%
mm_pix = P.mm_pix ;       % 0.5655 miliimeters/pixel
deg_pix = mm_pix/viewing_dist * 180/pi ;   % 0.045 degree/pixel, +/-10%

%GAMMA = P.LUT_params.gamma ;      % 1.5,  07-30-03
%BRstep = P.LUT_params.BRstep ;    %  24, hardwired

msec_frame = P.msec_frame ;        % 8.3 = 1000/120 ; (120 Hz)
pixel_depth = 32 ;      % must be 32 bits
if (~ismember(pixel_depth,SCREEN(whichScreen,'PixelSizes')))
   error('Sorry, I need a screen that supports 32-bit pixel depth.') ;
end
if (SCREEN('Preference','Backgrounding'))
   warning('I turn Backgrounding off because it confuses CharAvail.');
   SCREEN('Preference','Backgrounding',0) ;  % see CharAvail's help page
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%   PARAMETER DEFINITIONS   %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%- Main parameters are the same as in PLExp2 and PLExp1.
%- Gabor parameters. See PLEXP2_PARAMS and GABOR.M
%- Filtered noise parameters. See MAKE_PLE2_BACKGR, CACHE_PLE2_BACKGR.
%- Lookup table parameters. See IMAGE/MAKE_LINEAR_LUT.M
gray = P.colors.gray ;
%- Trial parameters


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%   REUSABLE DATA STRUCTS   %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%- P.mask_idx  -- See PLEXP2_PARAMS.M
%- P.Gabor -- See PLEX2_PARAMS, MAKE_PLE2_STIM, GABOR.M
%- P.Filter is not really necessary because of NOISE_CACHE global var
%- P.LUT -- lookup table, installed later.
%- P.sounds, P.fixation, and P.blank -- See PLEXP2_PARAMS.M


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%   ACQUAINT WITH PARTICIPANT   %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if (nargin < 2)  DB_spec = 'PLE2_subjects' ; end    % default

%-- Open the subject database
if (ischar(DB_spec))
   fprintf(outs,'Consulting the participant data base %s.mat...\n',...
           DB_spec) ;
   DB = open_sbj_database(DB_spec) ;
elseif (isstruct(DB_spec))
   DB = DB_spec ;
else
   error('DB_SPEC must be either a file name or a structure array.') ;
end

%-- Find the entry for this particular subject number. It should exist.
sbj_descr = find_sbj_descr(sbj_number,DB) ;
if (isempty(sbj_descr))
   error(['The data base contains no entry for subject ',...
         int2str(sbj_number),'.']) ;
%else information about this subject successfully retrieved from DB
end

%-- Make sure that phase 2 is completed
if (sbj_descr.session < 12)
   fprintf(outs,'\nSubject %d has only completed %d sessions.\n',...
           sbj_descr.sbj_number,sbj_descr.session-1) ;
   k = input('Are you sure you want to proceed with phase 3? (y) ','s') ;
   if (isempty(k))  k = 'y' ;  end   % default
   if (~ismember(k,'yY'))
      fprintf(outs,'OK. Nothing has been written to the hard disk.\n') ;
      fprintf(outs,'\n\nHave a nice day!\n\n') ;
      return
   %else  On experimenter's authority, proceed with session 12 anyway.
   end
end

%-- Make sure all fields of SBJ_DESCR are correct
sbj_descr    % print on console as a structure
k = input('Is this information correct? (y) ','s') ;
if (isempty(k))  k = 'y' ;  end   % default
if (~ismember(k,'yY'))
   fprintf(outs,'\n\nYou may edit the SBJ_DESCR variable.\n') ;
   fprintf(outs,'Type ''return'' to continue.\n\n') ;
   keyboard ;
end

%-- Save the (edited?) subject descriptor in the database
DB = update_sbj_database(sbj_descr,DB_spec) ;  % write file as side eff

%-- Individualized session parameters
sbj_number = sbj_descr.sbj_number ;
group = sbj_descr.group ;
session = sbj_descr.session ;          % should be 12
data_filename = sbj_descr.filename ;
NCache_sequence = sbj_descr.NCache_sequence ;

curr_schedule = schedule{group}(session-11,:) ;   % -(9+2) for phases 1+2
blocks_per_session = length(curr_schedule) ;          % 4
N_trials = trials_per_block * blocks_per_session ;    % 1248=312x4

% The NC_fnumbers on day 12 are the same as those on day 6.
NC_fnumber_offset = (6-1) * blocks_per_session ;

NCache_path = P.NCache_params.path ;           % 'PLE2_CACHE01'
NCache_template = P.NCache_params.fname ;      % 'L01_%03d.mat'


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%    SCREENS AND MOVIES     %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%-- Open a SCREEN window and set the lookup table
fprintf(outs,'\nOpening screen %d...',whichScreen) ;
[winPtr,winRect] = SCREEN(whichScreen,'OpenWindow',gray,[],pixel_depth) ;
fprintf(outs,'   Done.\nSetting the lookup table...') ;
SCREEN(winPtr,'SetClut',P.LUT) ;
SCREEN(winPtr,'FillRect',gray) ;    % clear the screen
fprintf(outs,'   Done.\n') ;

%-- Convert stimulus duration from milliseconds to video frames
N_frames = round(P.duration / msec_frame) ;
if (abs(N_frames - (P.duration/msec_frame)) > 0.01)
   warning('Stimulus duration is not an integer number of frames.') ;
end
P.times.target_play = (N_frames+1) * msec_frame/1000 ;  % one blank frame

%-- Create one movieStruct for each stimulus position
fprintf(outs,'Creating offscreen buffers...') ;
P.movieStruct(1) = MakeMovieStruct(winPtr,repmat(P.size,2,1),...
                                   P.position{1},[1 2],[N_frames 1]) ;
for k = 2:length(P.position)
   P.movieStruct(k) = CloneMovieStruct(P.movieStruct(1),P.position{k}) ;
end
fprintf(outs,'   Done.\n') ;

%%%%%%  At this point, P is ready to be passed to DO_PLE2_TRIAL.  %%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%    PREPARATION    %%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%-- Open the data file
fprintf(outs,'Opening data file %s...',data_filename) ;
[data_fid,errmsg] = fopen(data_filename,'at') ;   % mode = append text
if (data_fid == -1)
   warning(errmsg) ;
   fprintf(outs,'Fix the problem and type ''return'' to continue.\n\n') ;
   keyboard ;
else
   fprintf(outs,'   Done.\n') ;
end

%-- Open the sound channel
fprintf(outs,'Opening the sound channel...') ;
SND('Open') ;
fprintf(outs,'   Done.\n') ;

%-- Start various counters
data = zeros(N_trials+200,21) ;   % 200 reserve rows
d = zeros(1,21) ;

time_zero = GetSecs ;
exp_tr = 1 ;           % global trial number


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%        MAIN   LOOP        %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

for bl = 1:blocks_per_session   % for each block in the current session
   %- Keeping NCACHE_ORIENT fixed, counterbalance the IVs
   NCache_orient = curr_schedule(bl) ;
   block = factor_design(levels,replications ,1) ;   % randomized
   %- Load the appropriate NOISE_CACHE from the CD-ROM
   NCache_fnumber = NCache_sequence(NC_fnumber_offset+bl) ;
   NCache_fname = fullfile(NCache_path, ...
                sprintf(NCache_template{NCache_orient},NCache_fnumber)) ;
   fprintf(outs,'Loading stimuli from %s. Please wait ...',NCache_fname);
   SCREEN(winPtr,'WindowToFront') ;
	SCREEN(winPtr,'DrawText',['Loading stimuli, please wait...   ',...
             '(Take a break if you wish.)'],150,240,P.colors.black) ;
   NC_pages = load_NOISE_CACHE(NCache_fname,P.size) ;     % <-- sic!
   fprintf(outs,'   Done.\n') ;
   SCREEN(winPtr,'FillRect',gray) ;
   %- Generate randomized Noise Cache indices
   NC_idx = randomize_NC_idx(trials_per_block,NC_pages) ;
   %- Proceed when the participant is ready
   FlushEvents('keyDown') ;
   SCREEN(winPtr,'WindowToFront') ;
   ask(winPtr,'Please press Enter to proceed to the next trial... ',...
              P.colors.black,gray,'GetString') ;
   SCREEN(winPtr,'FillRect',gray) ;
   WaitSecs(0.800) ;
   %- Main trial loop
   tr = 1 ;      % block trial number, don't confuse with exp_tr
   while (tr <= size(block,1))
      % Present a stimulus and get a response from the subject
      spec = block(tr,1:3) ;    % [Gabor_orient,difficulty,position]
      flip = block(tr,4) ;      % -1=flip, +1=dont_flip
      spec(1) = spec(1)*flip ;  % flip Gabor_orient: 1==>-1, 2==>-2
      backgr_orient = NCache_orient*flip ;   % flip noise_orient
      record = do_PLE2_trial(P,spec(1),spec(2),NC_idx(tr),spec(3)) ;
      % Did everything go OK?
      exitcode = record(10) ;     % see DO_PLE2_TRIAL
      if (exitcode ~= 0)          % something went wrong
         block = [block ; [abs(spec),flip]] ;   % re-run at block end
         NC_idx = [NC_idx , NC_idx(tr)] ;
      end
      % Record data: 1=sbj, 2=group, 3=session, 4=block, 5=trial, ...
      d([1 2 3 4 5]) = [sbj_number group session bl exp_tr] ;
      d(6) = record(1) - time_zero ;    % 6=time stamp
      % 7=noise_orient, 8=noise_degr
      d(7) = backgr_orient ;            % 1=L,-1=R , 2=R,-2=L
      d(8) = P.noise_orient(NCache_orient)*180/pi * flip ; %-15,+15
      % 9=NC_file, 10=NC_idx
      d([9 10]) = [NCache_fnumber,record(4)] ;
      % 11=Gabor_orient, 12=Gabor_degr,
      d(11) = record(2) ;               % 1=L,-1=R , 2=R,-2=L
      d(12) = P.Gabor_orient(abs(record(2)))*180/pi * flip ;  %-10,+10
      % 13=diff, 14=Cpeak
      d([13 14]) = [record(3),P.Gabor_Cpeak(record(3))] ;
      % 15=position, 16=dy, 17=sanity_check
      d([15 16]) = [record(5),P.position{record(5)}(2)] ;
      d(17) = record(6) ;     % actual luminance of a particular pixel
      % 18=response, 19=correct, 20=RT, 21=exit_code
      d(18) = record(7) ;     % response key: 1="Left",2="Right"
      d(19) = record(8) ;     % correct, DO_PLE2_TRIALS handles phase 2 OK
      d(20) = record(9) ;     % response time, msec
      d(21) = record(10) ;    % exitcode: 0=OK,1=badKey,2=missFr
      % Write data file. See IMPORT2_PLE_DATA and the subfunction below.
      data(exp_tr,:) = d ;
      record_data_file(data_fid,d) ;
      % Move on to the next trial
      tr = tr+1 ;
      exp_tr = exp_tr+1 ;
      WaitSecs(P.times.ITI) ;
   end  % of the main trial loop
end  % of the block loop

data(exp_tr:end,:) = [] ;    % cut out unused reserve DATA rows


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%      SHOW DIAGNOSTIC RESULTS       %%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

ok = find((data(:,21)==0) & (data(:,4)>0)) ;    % valid non-demo trials
correct = data(ok,19) ;
RT = data(ok,20) ;
fprintf(outs,['\n%d trials completed. %4.1f percent correct. ',...
             'Median RT=%d msec.\n'],exp_tr-1,...
			 mean(correct)*100,round(median(RT)) ) ;
if (length(ok)==N_trials)                            % if all went well
	sz = [trials_per_block,blocks_per_session] ;     % [312x4]
	mnP = mean(reshape(correct,sz)) * 100 ;
	medRT = round(median(reshape(RT,sz))) ;
	fprintf(outs,'   P = [ ') ; fprintf(outs,'%4.1f ',mnP) ;
	fprintf(outs,']  ;  RT = [ '); fprintf(outs,'%d ',medRT) ;
	fprintf(outs,']\n\n') ;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%         CLEAN  UP         %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fprintf(outs,'Closing data file %s...',data_filename) ;
fclose(data_fid) ;
fprintf(outs,'   Done.\nClosing all screens and screen buffers...') ;
SCREEN('CloseAll') ;
fprintf(outs,'   Done.\nClosing the sound channel...') ;
SND('Close') ;
fprintf(outs,'   Done.\n') ;

%-- Update the subject database, if the name of the file is known
if (ischar(DB_spec))
   fprintf(outs,'Updating the participant data base %s...',DB_spec) ;
   session_log.session = session ;
   session_log.date = date ;            % e.g. '18-Aug-2003'
   session_log.trials = exp_tr-1 ;
   sbj_descr.session_log(end+1) = session_log ;
   sbj_descr.session = session + 1 ;    % prepare for next session
   DB = update_sbj_database(sbj_descr,DB_spec) ;  % write to file
   fprintf(outs,'   Done.\n') ;
end

fprintf(outs,'\nThank you for your participation. Have a nice day!\n\n') ;

%--- Return DATA and P
%%%  End of the main function


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% SUBFUNCTIONS

function  NC_pages = load_NOISE_CACHE(NCache_fname,sz)      %%%%%%%%%%%%%
% Update global variable NOISE_CACHE using the specified CD-ROM file.

global NOISE_CACHE

NOISE_CACHE = [] ;             % clear the old one
load(NCache_fname) ;           % <-- Sic!  Error-cheking below

[NC_rows,NC_cols,NC_pages] = size(NOISE_CACHE) ;
if (NC_rows~=sz(1) | NC_cols~=sz(2))
   NC_pages = 0 ;
   warning(sprintf('Failed to load NOISE_CACHE from %s.',NCache_fname)) ;
   fprintf(outs,'Fix the problem and type ''return'' to continue.\n\n') ;
   keyboard ;
%else  NC_pages correctly set
end

%-- Return NC_PAGES
%%% End of subfunction LOAD_NOISE_CACHE


function  NC_idx = randomize_NC_idx(N_trials,NC_pages)
% Make sure that there is a valid Noise Cache index for each trial

if (NC_pages==N_trials)     % the typical case
   NC_idx = randperm(NC_pages) ;        % use each exactly once
else         % in case I generate larger/smaller caches later
   NC_pool = repmat(randperm(NC_pages),1,ceil(N_trials/NC_pages)) ;
   NC_idx = NC_pool(1:N_trials) ;
end

%-- Return NC_IDX
%%% End of subfunction RANDOMIZE_NC_IDX


function  record_data_file(dfid,d)      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Write data file, see IMPORT_PLE2_DATA
% There are small differences relative to PLExp2:record_data_file:
% columns 7 (noise_orient) and 11 (Gabor_orient) now print an explicit
% '+' or '-' sign to indicate the flip. All else is the same.

% 1=sbj, 2=group, 3=session, 4=block, 5=trial
fprintf(dfid,'%02d %2d %2d %2d %4d',d(1:5)) ;
fprintf(dfid,'%10.3f  ',d(6)) ;            % 6=time stamp
% 7=noise_orient, 8=noise_degr, 9=NC_file, 10=NC_idx
fprintf(dfid,'%+2d %+5.1f %03d %03d ',d(7:10)) ;
% 11=Gabor_orient, 12=Gabor_degr, 13=diff, 14=Cpeak
fprintf(dfid,'%+2d %+5.1f %3d %4.2f  ',d(11:14)) ;
% 15=position, 16=dy, 17=sanity_check
fprintf(dfid,'%2d %+5d  %3d   ',d(15:17)) ;
% 18=response, 19=correct, 20=RT, 21=exit_code
fprintf(dfid,'%2d %2d %6d %2d\n',d(18),d(19),round(d(20)),d(21)) ;

%-- Return no value
%%% End of subfunction RECORD_DATA_FILE
