function runstim(Hnd)
 %Updated 19_10_2011 Chris van der Togt

 global Par   %global parameters
 global LPStat  %das status values
 global StimObj %stimulus objects

 if ~isfield(StimObj, 'Stm')
     disp('ERROR: No stimulus');
     return
 end

 Times = Par.Times; %copy timing structure
 BG = Par.BG; %background Color
 cgflip(BG(1), BG(2), BG(3))

 Stms = StimObj.Stm;   %all stimuli
 Objs = StimObj.Obj;   %all graphical objects
 IDs = [ Objs(:).Id ]; %Ids of all graphical objects

 %they should all be not loaded, but just to make sure
  for i = 1:length(IDs)
      if strcmp(Objs(i).Type, 'Texture') || strcmp(Objs(i).Type, 'Bitmap') || strcmp(Objs(i).Type, 'Bezier')
           Objs(i).Data.isLoaded = false;
      end
  end

 %....EVENTS.........................
 FIX = 1;
 STM = 2;
 TARG = 3;
 TARGOF = 4;
 %MICR = 5;
FS = 0;
FO = 0;

%////YOUR STIMULATION CONTROL LOOP /////////////////////////////////
   Hit = 2;
   Par.ESC = false; %escape has not been pressed
   while ~Par.ESC
       %Pretrial

%SETUP YOUR STIMULI FOR THIS TRIAL

    if Par.Drum && Hit ~= 2 %if drumming and this was an error trial
        %just redo with current sttings
    else
    %randomization
        I = ceil(rand*length(Stms));
        %or use custom randomisation procedure

        %condition and associated stimuli
        EVENT = Stms(I).Event;
        %calllib(Par.Dll, 'DO_Word', I); %send word bit and condition
        dasword( I); %send word bit and condition

    %timing
        PREFIXT = Times.ToFix; %time to enter fixation window
        FIXT = fix(Times.Fix + rand*Times.RndFix); %time to fix before stim onset
        STIMT = fix(Par.Times.Stim + rand*Times.RndStim); %time that stimulus is displayed
        TARGT = fix(Times.Targ + round(2*rand-1)*Times.RndTarg); %time to fix before target onset
        RACT = Times.Rt;      %reaction time

        FLtime = Par.fliptime;  %adjusting for fliptime
        STIMT = (round(STIMT/FLtime) - 0) * FLtime;
        TARGT = (round(TARGT/FLtime) - 0) * FLtime;

    %control window setup
        FI = find(IDs == Stms(I).Fix, 1);
        TI = find(IDs == Stms(I).Targ, 1);
        WIN = [ Objs(FI).Data.cx,  Objs(FI).Data.cy, Par.PixPerDeg*Par.FixWdDeg, Par.PixPerDeg*Par.FixHtDeg, 0; ... %Fix
                Objs(TI).Data.cx,  Objs(TI).Data.cy, Par.PixPerDeg*Par.TargWdDeg, Par.PixPerDeg*Par.TargHtDeg, 2 ];   %Targ
        Par.OFFx = Objs(FI).Data.cx;
        Par.OFFy = Objs(FI).Data.cy;

        Alt = Stms(I).Talt{:};
        for k = 1:length(Alt)
            AI = find(IDs == Alt(k), 1);
            WIN = [ WIN; ...
                    Objs(AI).Data.cx,  Objs(AI).Data.cy, Par.PixPerDeg*Par.TargWdDeg, Par.PixPerDeg*Par.TargHtDeg, 1 ]; %TAlt
        end
        Par.WIN = WIN';

     %preload tectures and bitmaps

         Ids = unique([EVENT{:}]); %get all object ids in stimulus
         Notused = setxor(IDs, Ids);
        %free memory of obsolete sprites
        for id = Notused %indices into notused objects
            idx = find(IDs == id); %obtain index to the object corresponding with this id
            if strcmp(Objs(idx).Type, 'Texture') || strcmp(Objs(idx).Type, 'Bitmap') || strcmp(Objs(idx).Type, 'Bezier')
                if Objs(idx).Data.isLoaded
                    cgfreesprite(id) %unload this sprite to make memory free
                    Objs(idx).Data.isLoaded = false;
                end
            end
        end
        %load new sprites
        for id = Ids
           idx = find(IDs == id);
           if strcmp(Objs(idx).Type, 'Texture')
               OBJ = Objs(idx).Data;
               if ~(OBJ.isLoaded) %is not loaded
                    Objs(idx).Data = cgTexture(OBJ, 'L', id); %(L)oad the texture
               end
           elseif strcmp(Objs(idx).Type, 'Bitmap')
               OBJ = Objs(idx).Data;
               if ~(OBJ.isLoaded) %is not loaded
                    Objs(idx).Data = cgBitmap(OBJ, 'L', id); %Load the bitmap
               end
           elseif strcmp(Objs(idx).Type, 'Bezier')
               OBJ = Objs(idx).Data;
               if ~(OBJ.isLoaded) %is not loaded
                    Objs(idx).Data = cgBezier(OBJ, 'S', id); %draw the bezier on a sprite
               end
           end
        end
    end
%/////////////////////////////////////////////////////////////////////
%START THE TRIAL
    %set control window positions and dimensions
    refreshtracker(1) %for your control display
    SetWindowDas      %for the dascard, initializes eye control windows
    Abort = false;    %whether subject has aborted before end of trial

%///////// EVENT 0 START FIXATING //////////////////////////////////////

    %cgellipse(Px,Py,20,20,[1 0 0 ],'f') %the red fixation dot on the screen
    cgplotstim(EVENT{FIX}, Objs);
    cgflip(BG(1), BG(2), BG(3))

     dasreset( 0 )  %test enter fix window
    %     0 enter fix window
    %     1 leave fix window
    %     2 enter target window


    %LPStat(1) = time (ms) passed since last reset
    %LPStat(2) = control window hit (1 : in or out, 2 : in correct
    %                  target window
    %LPStat.(3) = hit position x
    %LPStat(4) = hit postion y
    %LPStat(5) = reaction time
    %LPStat(6) = time saccade length


     %subject has to start fixating central dot
    Par.SetZero = false; %set key to false to remove previous presses
    %Par.Updatxy = 1; %centering key is enabled
    Time = 1;
    Hit = 0;
    while Time < PREFIXT && Hit == 0
        pause(0.05)

       [Hit Time] = DasCheck; %retrieve position values and plot on Control display
    end

%///////// EVENT 1 KEEP FIXATING or REDO  ////////////////////////////////////

    if Hit ~= 0  %subjects eyes are in fixation window keep fixating for FIX time
        %the tril bit has now automatically been set high!! If the monkey
        %loses fixation he gets another chance but the tril bit just stays
        %high and this results in a longer prestim period
        dasreset( 1 );  %set test parameters for exiting fix window

        Time = 1;
        Hit = 0;
        while Time < FIXT && Hit== 0
            %Check for 10 ms
            pause(0.005)

              %detect eye enter/exit of control windows
                                            %this will also automaitcally
                                            %occur during pauzes due to a
                                            %callback routine run every single ms
            [Hit Time] = DasCheck; %retrieve eyechannel buffer and events, plot eye motion,
        end


        if Hit ~= 0 %eye has left fixation to early
                %possibly due to eye overshoot, give subject another chance
                dasreset( 0 );
                Time = 1;
                Hit = 0;
                while Time < PREFIXT && Hit == 0
                    pause(0.005)
                    [Hit Time] = DasCheck; %retrieve position values and plot on Control display
                end
             if Hit ~= 0  %subjects eyes are in fixation window keep fixating for FIX time
                dasreset( 1 );  %test for exiting fix window

                Time = 1;
                Hit = 0;
                while Time < FIXT && Hit == 0
                    %Check for 10 ms
                    pause(0.005)
                    [Hit Time] = DasCheck;
                end
             else
                  Hit = -1; %the subject did not fixate
             end
        end

    else
        Hit = -1; %the subject did not fixate
    end

%///////// EVENT 2 DISPLAY STIMULUS //////////////////////////////////////
     if Hit == 0 %subject kept fixation, display stimulus
        Par.Trlcount = Par.Trlcount + 1;  %counts total number of trials for this session

%change your display between these lines.......................
%             cgpencol(1,1,1)
%             cgrect(-462, 334, 100, 100) %test stimulus for light diode
%             cgellipse(Px,Py,20,20,[1 0 0 ],'f') %fixation dot
%             cgellipse(Par.WIN(1,2), Par.WIN(2,2), 20, 20, [1 0 0 ], 'f') %target
        cgplotstim(EVENT{STM}, Objs);
 %..............................................................
        FO = cgflip(BG(1), BG(2), BG(3));
        FS = FO;
        %cgflip('v'); %this is not nice; cgflip does not give good timing
        tic  %measure onset too
        dasbit( Par.StimB, 1);   %send stimulus bit to TDT
        dasreset( 1 );  %test for exiting fix window
        refreshtracker(2)  %set target window to green
        Time = 0;

 %prepare display for next flip TARGON.................
        if ~isempty(EVENT{TARG})
                cgplotstim(EVENT{TARG}, Objs);
                EPoch = min( STIMT-10, TARGT-50); %determine smallest time
                while Time < EPoch  && Hit == 0
                     dasrun( 5 );
                    %get hit time
                    [Hit Time] = DasCheck;
                end
                FS = cgflip(BG(1), BG(2), BG(3));

        end
        if ~isempty(EVENT{TARGOF})
                    cgplotstim(EVENT{TARGOF}, Objs);
               %prepare display for next flip.................
        end

        while Time < TARGT-50  && Hit == 0  %Keep fixating till just before (50ms) target onset
                dasrun( 5 );
                %get hit time and plot eyemotion
                [Hit Time] = DasCheck; %plot eye motion in tracker
        end

            %how much time(ms) do we have left till target onset???  +
            %FlOP* FLtime
            delay = floor(TARGT - toc*1000 - FLtime/2); %hold up calling the next flip
            if delay > 0
                %calllib(Par.Dll, 'Check', delay)
                dasrun(delay)
                Hit = LPStat(2);  %don't wast time!!!! on updating the screen
            else
                disp('WARNING....not enough time between stimoffset and target onset.')
            end

%///////// EVENT 3 TARGET ONSET, REACTION TIME%%//////////////////////////////////////

        if Hit == 0 %subject kept fixation, subject may make an eye movement
            FS = cgflip(BG(1), BG(2), BG(3));
        %    cgflip('v');    %this is not nice; cgflip doesnot give good timing
            dasbit( Par.TargetB, 1); %send target bit to TDT
            dasreset(2);            %reset counter and check for entering target window
            %toc      %display this to check your internal timing
            refreshtracker(3) %set fix point to green

            Time = 0;
            while Time < RACT && Hit <= 0  %RACT = time to respond (reaction time)
                %Check for 5 ms
                dasrun( 5)
                [Hit Time] = DasCheck;
            end

        else
            Abort = true;
        end
        %END EVENT 3
    else
        Abort = true;
    end
    %END EVENT 2
    cgflip(BG(1), BG(2), BG(3));

  %///////// POSTTRIAL AND REWARD //////////////////////////////////////
        if Hit ~= 0 && ~Abort %has entered a target window (false or correct)

            if Par.Mouserun
                HP = line('XData', Par.ZOOM * (LPStat(3) + Par.MOff(1)), 'YData', Par.ZOOM * (LPStat(4) + Par.MOff(2)), 'EraseMode','none');
            else
               HP = line('XData', Par.ZOOM * LPStat(3), 'YData', Par.ZOOM * LPStat(4), 'EraseMode','none');
            end
            set(HP, 'Marker', '+', 'MarkerSize', 20, 'MarkerEdgeColor', 'm')
            %drawnow

            if Hit == 2 && Par.Reward && LPStat(6) < Times.Sacc %correct target, give juice

                    dasbit( Par.CorrectB, 1);
                    dasbit( Par.RewardB, 1);
                    dasjuice( 5 );
                    Par.Corrcount = Par.Corrcount + 1; %log correct trials
                   % beep

                    pause(Par.RewardTime) %RewardTime is in seconds

                    dasbit( Par.RewardB, 0);
                    dasjuice( 0 );


            elseif Hit == 1
                    dasbit(  Par.ErrorB, 1);
                    Par.Errcount = Par.Errcount + 1;
                   %in wrong target window
            end

            %keep following eye motion to plot complete saccade
            for i = 1:10   %keep targoff for 50ms
                pause(0.005) %not time critical, add some time to follow eyes
            %calllib(Par.Dll, 'Check', 5);
            DasCheck; %keep following eye motion
            end
            %Save_eyetrace( I )

        end

         if Hit ~= 2  %error response
              %add pause when subject makes error
             for i = 1:round(Times.Err/5)   %keep targoff for Times.Err(ms)
                 pause(0.005)
                % calllib(Par.Dll, 'Check', 5);
                DasCheck;
             end

         end
         [ Hit Lasttime] = DasCheck;
%///////////////////////INTERTRIAL AND CLEANUP
         display(['hit ' num2str(Hit) ' reactiontime: ' num2str(LPStat(5))  ' saccadetime: ' num2str(LPStat(6))]);
         disp(['stimulus-target duration: ' num2str((FS - FO)*1000) ' ms ']);  %check timing of target onset

         %reset all bits to null
         for i = [0 1 2 3 4 5 6 7]  %Error, Stim, Saccade, Trial, Correct,
             %calllib(Par.Dll, 'DO_Bit', i, 0);
             dasbit( i, 0); %clear bits
         end
         %calllib(Par.Dll, 'Clear_Word');
         dasclearword();

            SCNT = {'TRIALS'};
            SCNT(2) = { ['N: ' num2str(Par.Trlcount) ]};
            SCNT(3) = { ['C: ' num2str(Par.Corrcount) ] };
            SCNT(4) = { ['E: ' num2str(Par.Errcount) ] };
            set(Hnd(1), 'String', SCNT ) %display updated numbers in GUI

            SD = dasgetnoise();
            SD = SD./Par.PixPerDeg;

            set(Hnd(2), 'String', SD )

         cgpencol(BG(1), BG(2), BG(3)) %clear background before flipping
         cgrect
         cgflip(BG(1), BG(2), BG(3))
         %pause( Times.InterTrial/1000 ) %pause is called with seconds
                                       %Times.InterTrial is in ms
         Time = Lasttime;
         while Time < Times.InterTrial + Lasttime
             pause(0.005)
             %calllib(Par.Dll, 'Check', 5);
            [Hit Time] = DasCheck;
         end

   end   %WHILE_NOT_ESCAPED%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Attempt to reference field of non-structure array.

Error in ==> runstim at 13
 Times = Par.Times; %copy timing structure