function lyngby_ui_preproc_detrend(command,parameter1)

% lyngby_ui_preproc_detrend  - UI for setting up preprocessing parameters
%                               for Cyrill Goutte's detrending method.
%
%       function lyngby_ui_preproc_detrend(command,parameter1) 
%
%       This is the function that controls the user interface for the
%       setup of the preprocessing parameters. The function is
%       automatically called from lyngby_ui_preproc when the user
%       chooses the 'Detrend' algorithm from the list box. 
%         
%       This detrending removes a (different) linear trend for
%       each run and for each voxel.

%  
%       The method estimates the trends within each run by using
%       the frames from 2 'detrend windows' created on either side
%       of the activation. The first window ends just before the
%       activation starts. The second window ends at the end of the
%       run. The width of the windows is therefore determined from
%       the design of your experiment. Obviously, the more frames
%       you can include, the better the estimation. But it is
%       advisable keep the first window small enough so that it avoids
%       being too near the start of the run (to avoid saturation
%       effects etc). Also, there will be a period after the
%       activation has finished which you need to avoid using for
%       the estimation because the activation needs time to
%       decay. A reasonable estimate for this is 5-10 seconds. (The
%       current minimum is set to 5 seconds, but you can alter this
%       if required by changing the field in the code. Look for
%       the line "% <<<<< You may change this variable if >>>>>>"
%       in the file lyngby_ui_preproc_detrend.m). So the width of 
%       the windows is therefore a trade-off between getting as
%       many frames as possible, in order to get the best
%       estimation, and staying as far away as possible from any 
%       non-baseline frames. 
%  
%       You will see that you have 2 variables to alter - the TR
%       (the number of seconds per frame), and the width of the
%       windows. The code will help you (as much as possible) in
%       trying to detect when the parameters you specify are
%       incorrect or do not leave enough time for the activation to
%       decay, etc. The main thing to remember is that you need an
%       activation function which has sufficient TIME, BOTH before AND
%       after the activation, for the method to work sufficiently. 
%
%       This method is mainly designed for an off-on-off,
%       boxcar-type paradigm, with one activation per run. But as
%       long as you have sufficient frames at the start and end of
%       each run, the method will work for almost any design, even
%       for multiple activations per run. Of course, the robustness
%       of the method will vary depending upon the specifics of
%       your design. Note that the run variable is there to specify
%       the trial periods, and so any short breaks between trials
%       (e.g. a minute's rest whilst the scanner is reset) is
%       indicated by a different run index. This is the reason for
%       using the run variable for specifying the extent of the
%       period from which to estimate a trend (as the estimation of a
%       trend across trial 'pauses' would be confounded by the
%       changes introduced by the break).
%       
%       After you have specified the parameters, you can see which
%       frames will be used for the trend estimation by clicking on
%       the "View plot of detrend frames' button. This will open a
%       window showing the paradigm and run variables, together
%       with the frames to be used in the method highlighted in
%       red.
%  
%       When you are happy with the choice of parameters, click on
%       the 'Apply Detrending' button. The log-line at the bottom
%       of the main Lyngby window will show you when it is
%       finished. Also, a log of the variables used will be entered
%       into the right-hand pane of the main pre-processing window
%       for future reference (Remember to save the logfile if you
%       so require - use the 'Option' menu).
%  
%       After the detrending has finished, you can view the results
%       of the method by clicking on the 'View removed trends'
%       button. This will pop-up the standard Lyngby triple set of
%       viewing windows, showing the data before the trends were
%       removed, the actual trends calculated and removed, the
%       paradigm and the run functions. Note that this is mainly
%       for illustrative purposes, as the undetrended data (in
%       green) has been artificially centered to make plotting
%       easier. The same is true for the trends. If you want to see
%       how the data looks AFTER the detrending has been performed,
%       simply click the 'View Data' button in the main
%       pre-processing window.
%  
%       Click on the 'Close' button once you have finished.  
%
%       Ref: Goutte et al, "Feature-space clustering for fMRI
%            meta-analysis", Human Brain Mapping, 13(3):165-183.
%
%       See also LYNGBY, LYNGBY_NORMALIZE, LYNGBY_PREP_GLOBAL, 
%                LYNGBY_UI_PREPROC, LYNGBY_UI_VIEW_DETREND
%  
% $Id: lyngby_ui_preproc_detrend.m,v 1.3 2002/05/19 22:18:56 fnielsen Exp $

%  Made with Gui Maker Ver 2.1 by Patrick Marchand
%
%  Created: 27-Nov-96 
%  Using  : GUI Maker Ver 2.1 by Patrick Marchand 
%                         (PRMarchand@aol.com) 
%  Copyright (c)   
%       Permission is granted to modify and re-distribute this 
%	code in any manner as long as this notice is preserved. 
%	All standard disclaimers apply. 




     lyngby_ui_global;
     lyngby_ui_option;
     lyngby_prep_global;
 
     % Added this to enable access to PARADIGM etc..
     lyngby_global;
     
 
     global RUN            % Workaround for the RUN run.m problem in Windows. 
%    global DETREND_LOG    % Local log record
     global FULL_INDEX_DETREND % So it's accessible from the plot, and easy to update

     
    % --- Tooltips ---
    % This function toggles the state of the tooltips help.
    ToggleTooltips = [ ...
	  'ver = (version);', ...
	  'ver = str2num(ver(1:3));', ...
	  'if ver >= 5.2 & strcmp(get(menuTooltips, ''Checked''), ''on''),',...
	  '  UI_TOOLTIPS = 0;',...
	  '  set(menuTooltips, ''Checked'',''off'');',...
	  '  set(buttonClose, ''TooltipString'','''');',...
	  '  set(buttonApply, ''TooltipString'','''');',...
	  '  set(buttonHelp, ''TooltipString'','''');',...
	  'elseif ver >= 5.2,',...
	  '  UI_TOOLTIPS = 1;',...
	  '  set(menuTooltips, ''Checked'',''on'');',...
	  '  set(buttonClose, ''TooltipString'',''Close window without doing pre-processing'');',...
	  '  set(buttonApply, ''TooltipString'',''Close window and do the selected pre-processing'');',...
	  '  set(buttonHelp, ''TooltipString'',''Help for this window'');',...
	  'end,',...
	  ];


    UpdateAllFields = [ ...      % This just places the current values into the edit boxes
	'if (TR~=0),',...            % TR set, therefore make 'seconds' fields visible  
	'  set(textSecondsTitle, ''Enable'', ''on'');',...
	'  set(textWinWidthSeconds, ''Enable'', ''on'');',...
	'  set(textDecayGapSeconds, ''Enable'', ''on'');',...
	'  set(editTr, ''String'', TR);',...               % Put new values in
	'  set(editWinWidthFrames, ''String'', WINWIDTH_F);',...
	'  set(textWinWidthSeconds, ''String'', WINWIDTH_S);',...
	'  set(textDecayGapFrames, ''String'', POSTGAP_F);',...
	'  set(textDecayGapSeconds, ''String'', POSTGAP_S);',...
	'  MIN_GAP_DECAY_F=ceil(MIN_GAP_DECAY_S/TR);',...    % Required for checking window sizes
	'else,',...                  % TR not set, therefore make ''seconds'' fields invisible	  
	'  set(textSecondsTitle, ''Enable'', ''off'');',...
	'  set(textWinWidthSeconds, ''Enable'', ''off'');',...
	'  set(textDecayGapSeconds, ''Enable'', ''off'');',...	  
	'  set(editTr, ''String'', '''');',...             % Put new values in, and blank the seconds fields
	'  set(editWinWidthFrames, ''String'', WINWIDTH_F);',...
	'  set(textWinWidthSeconds, ''String'', '''');',...
	'  set(textDecayGapFrames, ''String'', POSTGAP_F);',...
	'  set(textDecayGapSeconds, ''String'', '''');',...
	'  MIN_GAP_DECAY_F=0;',...    % Cannot calc if no TR given, therefore allow to be zero (allows for overriding of min-gap requirement)
	'end;',...
	  ];
    
    % This updates the GUI depending on whether the gap is too small or not
    UpdateSmallGap = [ ...
      'lyngby_ui_message(''The gap between the end of the ' ...
      'activation period and the start of the detrend window ' ...
      'is too small! For the current value of TR, you need ' ...
      'more frames to allow the haemodynamic response to ' ...
      'decay away.'');' ...
	  ];

    % This updates the GUI and gives a warning if the detrend windows
    % are too large 
    UpdateBigFrontWindow = [ ...
	  'lyngby_ui_message(''The detrend windows are too large for ' ...
	  'the space available before the paradigm.'');' ...
	  ];

    % This updates the GUI and gives a warning if the detrend windows
    % are too large 
    UpdateBigEndWindow = [ ... 
	  'lyngby_ui_message(''The detrend windows are too large ' ...
	  'for the space available after the paradigm (including ' ...
	  'a period to allow for haemodynamic decay.'');' ...
	  ];
    
    % This updates the GUI and gives a warning if the detrend windows
    % are too large 
    UpdateBigEndWindowTR = [ ... 
	  'lyngby_ui_message(sprintf(''With the new value of TR, ' ...
	  'the detrend windows now occur too soon after the ' ...
	  'paradigm activation to allow for complete ' ...
	  'haemodynamic decay. The minimum number of seconds ' ...
	  'required to allow complete decay is currently set to ' ...
	  '%6.2f, which means you need at least %d frames ' ...
	  'between the activation and detrend window.'', ' ...
	  'MIN_GAP_DECAY_S, MIN_GAP_DECAY_F));' ...
	  ];
    
    % This stores all the variables in the window's 'userdata'
    % property as a structure 
    UpdateVariableDB = [ ... 
	  'detrendwindata.detrendlog = DETREND_LOG;',...
	  'detrendwindata.winwidthf = WINWIDTH_F;',...
	  'detrendwindata.winwidths = WINWIDTH_S;',...
	  'detrendwindata.postgapf = POSTGAP_F;',...
	  'detrendwindata.postgaps = POSTGAP_S;',...
	  'detrendwindata.winerror = WIN_ERROR;',...
	  'detrendwindata.runlengthf = RUNLENGTH_F;',...
	  'detrendwindata.numruns = NUM_RUNS;',...
	  'detrendwindata.tr = TR;',...
	  'detrendwindata.beginactf = BEGIN_ACT_F;',...
	  'detrendwindata.endactf = END_ACT_F;',...
	  'detrendwindata.mingapdecayf = MIN_GAP_DECAY_F;',...
	  'detrendwindata.mingapdecays = MIN_GAP_DECAY_S;',...
	  'detrendwindata.currentindex = CURRENT_INDEX;',...
	  'detrendwindata.indexdetrend = INDEX_DETREND;',...
	  'detrendwindata.fullindexdetrend = FULL_INDEX_DETREND;'...
	  'set(h_fig_list,''userdata'',detrendwindata); ',...
	  ];
    
    if nargin == 0 
      command = 'new'; 
    end 

    if isstr(command) 
      if strcmp(lower(command),'initialize') | strcmp(lower(command),'new') 
	command = 0; 
      elseif strcmp(lower(command),lower('buttonClose')) 
	command = 1; 
      elseif strcmp(lower(command),lower('buttonApply')) 
	command = 2; 
      elseif strcmp(lower(command),lower('buttonHelp')) 
	command = 3; 
      elseif strcmp(lower(command),lower('editTr')) 
	command = 4; 
      elseif strcmp(lower(command),lower('editWinWidthFrames')) 
	command = 5; 
      elseif strcmp(lower(command),lower('textWinWidthSeconds')) 
	command = 6; 
      elseif strcmp(lower(command),lower('textDecayGapFrames')) 
	command = 7; 
      elseif strcmp(lower(command),lower('textDecayGapSeconds')) 
	command = 8; 		
      elseif strcmp(lower(command),lower('buttonCallPlot')) 
	command = 9; 
      elseif strcmp(lower(command),lower('buttonViewResults')) 
	command = 10; 
      elseif strcmp(lower(command),lower('ToggleTooltips'))
	command = 100;
      end 
    end 

    if command ~= 0 
      h_fig_list = findobj(get(0,'children'),'flat',... 
	  'tag','lyngby_ui_preproc_detrend'); 
      if length(h_fig_list) > 1 
	h_fig_list = gcf; 
      elseif length(h_fig_list) == 0 
	error('There are no figures with Tag = lyngby_ui_preproc_detrend.'); 
      end 
      detrendwindata = get(h_fig_list,'userdata');
      handle_list = detrendwindata.handlelist;

      if length(handle_list) > 0 
	frameTop = handle_list(1);
	frameBottom = handle_list(2);
	textTopTitle = handle_list(3);

	buttonClose = handle_list(4); 
	buttonApply = handle_list(5); 
	buttonHelp = handle_list(6); 

	textTr = handle_list(7);
	editTr = handle_list(8);
	textTrSecs = handle_list(9);
	textFramesTitle = handle_list(10);
	textSecondsTitle = handle_list(11);

	textWinWidth = handle_list(12);
	editWinWidthFrames = handle_list(13);
	textWinWidthSeconds = handle_list(14);

	textDecayGap = handle_list(15);
	textDecayGapFrames = handle_list(16);
	textDecayGapSeconds = handle_list(17);
	buttonNote = handle_list(18);
	buttonCallPlot = handle_list(19); 
	buttonViewResults = handle_list(20);
	
	menuOptions = handle_list(21);
	menuTooltips = handle_list(22);
      end 
      % Load variable data from window into local copies
      DETREND_LOG = detrendwindata.detrendlog;
      WINWIDTH_F = detrendwindata.winwidthf;
      WINWIDTH_S = detrendwindata.winwidths;
      POSTGAP_F = detrendwindata.postgapf;
      POSTGAP_S = detrendwindata.postgaps;
      WIN_ERROR = detrendwindata.winerror;
      RUNLENGTH_F = detrendwindata.runlengthf;
      % RUNLENGTH_S = detrendwindata.runlengths;
      % NUM_RUNS = detrendwindata.numruns;
      TR = detrendwindata.tr;
      BEGIN_ACT_F = detrendwindata.beginactf;
      % BEGIN_ACT_S = detrendwindata.beginacts;
      END_ACT_F = detrendwindata.endactf;
      % END_ACT_S = detrendwindata.endacts;
      MIN_GAP_DECAY_F = detrendwindata.mingapdecayf;
      MIN_GAP_DECAY_S = detrendwindata.mingapdecays;
      CURRENT_INDEX = detrendwindata.currentindex;
      INDEX_DETREND = detrendwindata.indexdetrend;
      FULL_INDEX_DETREND = detrendwindata.fullindexdetrend;
      % End load variables    
    end 


    if command == 0 

      fig = figure('position',[ 230 188 450 250 ],... 
	  'resize','On','tag','lyngby_ui_preproc_detrend',... 
	  'menubar','None','name','Lyngby - Pre-Processing - Linear Detrending',... 
	  'numbertitle','Off','visible','off', ...
	  'color', UI_COLOUR_WINBACK); 

      h1 = 0.08;  % Standard buttons
      h2 = 0.1; % Bottom row buttons
      h3 = 0.19; % Main Title height
      h4 = 0.02; % Vertical offset to align edit and text boxes       

      w1 = 0.20; % Small bottom-row buttons
      w2 = 0.40; % Large bottom-row button etc
      w3 = 0.085; % Edit fields
      w4 = 0.92; % Main Title width
      w5 = 0.12; % Column title width
      
      x1 = 0.04; % Left-most buttons etc
      x2 = 0.09;
      x3 = 0.30; % Middle buttons
      x4 = 0.50-(w3/2); % Tr edit box (centred)
      x5 = x4+(w3)+0.01; % Tr secs text box   
      x6 = 0.76; % Right buttons, plus left edit column
      x7 = x6+w1-w3; % Right edit column

      y1 = 0.015;    % Bottom frame
      y2 = 0.025+y1; % Bottom row buttons, lower frame
      y3 = 0.20;     % Top Frame
      y4 = 0.22; % Bottom button row, top frame
      y5 = 0.35; % Lower middle button row
      y6 = 0.48; % Upper middle button row
      y7 = 0.61; % Top button row
      y8 = 0.73; % Main title

      % Frames
      frameTop = uicontrol(...
	  'Units','normalized',... 
	  'ForegroundColor',UI_COLOR_FRONT,... 
	  'BackgroundColor',UI_COLOUR_FRAME,...
	  'Position',[ 0.0172 0.1693 0.9655 0.8124 ],... 
	  'String','',... 
	  'Style','frame',... 
	  'Tag','frameTop',... 
	  'UserData',''); 
      frameBottom = uicontrol(...
	  'Units','normalized',... 
	  'ForegroundColor',UI_COLOR_FRONT,... 
	  'BackgroundColor',UI_COLOUR_FRAME,...
	  'Position',[ 0.0172 y1 0.9655 0.15 ],... 
	  'String','',... 
	  'Style','frame',... 
	  'Tag','frameBottom',... 
	  'UserData',''); 

      % Titles etc
      textTopTitle = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textTopTitle'');',...  
	  'Units','normalized',... 
	  'Position',[ x1 y8 w4 h3 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_STATUS,... 
	  'String', [ ...
	    'This window controls the linear detrending ' ...
	    'performed upon the data. A linear trend is ' ...
	    'calculated for each ''run'' and voxel of ' ...
	    'the time-series, and removed. A window of ' ...
	    'frames before the activation, and another ' ...
	    'at a suitable period after the activation ' ...
	    'has stopped, are used to calculate the ' ...
	    'trend.' ...
	    ], ...
	  'Style','text',... 
	  'Tag','textTopTitle',... 
	  'UserData',''); 

      % Bottom panel control buttons
      buttonApply = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonApply'');',... 
	  'Units','normalized',... 
	  'Position',[ x3 y2 w2 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_BUTTON,... 
	  'String','Apply Detrending',... 
	  'Style','pushbutton',... 
	  'Tag','buttonApply',... 
	  'UserData',''); 
      buttonClose = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonClose'');',... 
	  'Units','normalized',... 
	  'Position',[ x1 y2 w1 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_BUTTON,... 
	  'String','Close',... 
	  'Style','pushbutton',... 
	  'Tag','buttonClose',... 
	  'UserData',''); 
      buttonHelp = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonHelp'');',... 
	  'Units','normalized',... 
	  'Position',[ x6 y2 w1 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_BUTTON,... 
	  'String','Help',... 
	  'Style','pushbutton',... 
	  'Tag','buttonHelp',... 
	  'UserData','');

      % Detrending Algorithm Buttons
      
      % Tr frames-seconds conversion
      textTr = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textTr'');',...  
	  'HorizontalAlignment','left',... 
	  'Units','normalized',... 
	  'Position',[ x1 y7-h4 0.44 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'String','Value of Tr (no. of seconds per frame):',... 
	  'Style','text',... 
	  'Tag','textTr',... 
	  'UserData',''); 
      editTr = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''editTr'');',...  
	  'Units','normalized',... 
	  'Position',[ x4 y7 w3 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'String','',... 
	  'Style','edit',... 
	  'Tag','editTr',... 
	  'UserData',''); 
      textTrSecs = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textTrSecs'');',...  
	  'Units','normalized',... 
	  'HorizontalAlignment','left',... 
	  'Position',[ x5 y7-h4 0.12 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'Enable', 'on',...
	  'String','seconds.',... 
	  'Style','text',... 
	  'Tag','textTrSecs',... 
	  'UserData',''); 
      textFramesTitle = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textFramesTitle'');',...  
	  'HorizontalAlignment','center',... 
	  'Units','normalized',... 
	  'Position',[ x6-((w5-w3)/2) y7-3*h4 w5 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'Enable', 'on',...
	  'String','Frames:',... 
	  'Style','text',... 
	  'Tag','textFramesTitle',... 
	  'UserData',''); 
      textSecondsTitle = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textSecondsTitle'');',...  
	  'HorizontalAlignment','center',... 
	  'Units','normalized',... 
	  'Position',[ x7-((w5-w3)/2) y7-3*h4 w5 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'Enable', 'off',...
	  'String','Seconds:',... 
	  'Style','text',... 
	  'Tag','textSecondsTitle',... 
	  'UserData',''); 

      % Number of frames to use for estimation of trend (width of dT)
      textWinWidth = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textWinWidth'');',...  
	  'HorizontalAlignment','left',... 
	  'Units','normalized',... 
	  'Position',[ x1 y6-h4 0.715 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'String','Width of the detrend window used on either side of the activation:',... 
	  'Style','text',... 
	  'Tag','textWinWidth',... 
	  'UserData',''); 
      editWinWidthFrames = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''editWinWidthFrames'');',...  
	  'Units','normalized',... 
	  'Position',[ x6 y6 w3 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'String','',... 
	  'Style','edit',... 
	  'Tag','editWinWidthFrames',... 
	  'UserData',''); 
      textWinWidthSeconds = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textWinWidthSeconds'');',...  
	  'Units','normalized',... 
	  'Position',[ x7 y6 w3 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_STATUS,... 
	  'Enable', 'off',...
	  'String','',... 
	  'Style','text',... 
	  'Tag','textWinWidthSeconds',... 
	  'UserData',''); 

      % Number of frames to leave between end of activation and
      % start of detrend window to allow for haemodynamic decay.      
      textDecayGap = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textDecayGap'');',...  
	  'HorizontalAlignment','left',... 
	  'Units','normalized',... 
	  'Position',[ x1 y5-h4 0.715 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_FRAME,... 
	  'String','Gap between end of the actvation and the second detrend window:',... 
	  'Style','text',... 
	  'Tag','textDecayGap',... 
	  'UserData',''); 
      textDecayGapFrames = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textDecayGapFrames'');',...  
	  'Units','normalized',... 
	  'Position',[ x6 y5 w3 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_STATUS,... 
	  'String','',... 
	  'Style','text',... 
	  'Tag','textDecayGapFrames',... 
	  'UserData',''); 
      textDecayGapSeconds = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''textDecayGapSeconds'');',...  
	  'Units','normalized',... 
	  'Position',[ x7 y5 w3 h1 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_STATUS,... 
	  'Enable', 'off',...
	  'String','',... 
	  'Style','text',... 
	  'Tag','textDecayGapSeconds',... 
	  'UserData','');       

      buttonNote = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonNote'');',... 
	  'Units','normalized',... 
	  'Position',[ x6 y4 w1 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', [ 1 0.193 0.215 ],... 
	  'String','Gap too small!!!',... 
	  'Style','pushbutton',... 
	  'Tag','buttonNote',... 
	  'Visible','off',...
	  'UserData',''); 
      
      
      % Call view window showing relationship between paradigm and
      %  the detrend frames
      buttonCallPlot = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonCallPlot'');',... 
	  'HorizontalAlignment','center',... 
	  'Units','normalized',... 
	  'Position',[ x1 y4 w2 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_BUTTON,... 
	  'String','View plot of detrend frames',... 
	  'Style','pushbutton',... 
	  'Tag','buttonCallPlot',... 
	  'UserData',''); 

      % Button to call a result-view triple-set showing the results
      % of the detrend algorithm
      buttonViewResults = uicontrol(... 
	  'CallBack','lyngby_ui_preproc_detrend(''buttonViewResults'');',... 
	  'HorizontalAlignment','center',... 
	  'Units','normalized',... 
	  'Position',[ (x6+w1-w2) y4 w2 h2 ],... 
	  'ForegroundColor', UI_COLOR_FRONT,...
	  'BackgroundColor', UI_COLOUR_BUTTON,... 
	  'String','View removed trends',... 
	  'Style','pushbutton',... 
	  'Tag','buttonViewResults',... 
	  'UserData',''); 

      % -- Menu Definitions etc --
      % Setup Menu controls
      ver = (version);
      ver = str2num(ver(1:3));
      if ver >= 5.2 
	menuOptions = uimenu( ...
	    'Parent',fig,...
	    'Label','Options',...
	    'Tag','TagMenuOptions',...
	    'Visible','on');
	menuTooltips = uimenu(...
	    'Parent',menuOptions,...
	    'Label','&Toggle Tooltips',...
	    'Checked','on',...
	    'Callback','lyngby_ui_preproc_detrend(''ToggleTooltips'');',...
	    'Tag','TagMenuTooltips',...
	    'Accelerator','T',...
	    'Visible','on');
      else
	menuOptions = 0;
	menuTooltips = 0;
      end
      
      % Test global Tooltips settings and set this window to the same
      if UI_TOOLTIPS == 0  
	eval(ToggleTooltips);
      end



      handle_list = [ ...  
	    frameTop frameBottom ...
	    textTopTitle ...
	    buttonClose buttonApply buttonHelp ... 
	    textTr editTr textTrSecs textFramesTitle textSecondsTitle ...
	    textWinWidth editWinWidthFrames textWinWidthSeconds  ...
	    textDecayGap textDecayGapFrames textDecayGapSeconds ...
	    buttonNote buttonCallPlot buttonViewResults ... 
	    menuOptions ...
	    menuTooltips ...
	    ]; 

      detrendwindata.handlelist = handle_list; %NEW
      set(gcf,'userdata',detrendwindata); 
      drawnow;pause(.1); 
      set(gcf,'visible','on'); 

    
      % ==================== INITIALISATION ========================
      % Initialize local log string...
      DETREND_LOG = '# Linear Detrending Routine:';
      
      % Initialise variables used for the detrend algorithm
      WINWIDTH_F=0; % Width of (both) detrend windows in frames
      WINWIDTH_S=0; %                   ""            in seconds
      POSTGAP_F=0;  % Gap between end of activ and detrend win (frames)
      POSTGAP_S=0;  %                   ""           (seconds)
      WIN_ERROR=1;  % Determines whether or not the window parameters are valid
		    % for calculating the detrending
      if ((exist('NUM_RUNS')==1)&(isempty(NUM_RUNS)~=1)&(NUM_RUNS~=0)), 
	RUNLENGTH_F=length(R)/NUM_RUNS; % Length of a run after the timemask has been applied.
		 		        %  Assumes equal length runs throughout.
      else   % Calculate length of each run from R variable
	run1=find(R==1); % The first run will have indices of 1 in the R variable
	RUNLENGTH_F=length(run1);
      end
      first_run=P(1:RUNLENGTH_F,:);   % Extract the frames for the first run from the
				      %  unnormalised, but timemasked, paradigm. Requires the
				      %  paradigm to be (0=inactive, 1=active)
      activ_index=find(first_run);    % List of frames in first run with activation
      CURRENT_INDEX=P(1:RUNLENGTH_F,1);  % Set to same as first run % DEBUG
      FULL_INDEX_DETREND=zeros(length(R),1);         % The full index of detrend frames (to allow for non-identical
						     %  detrend windows for each run - in a future version)
      BEGIN_ACT_F=activ_index(1)-1;   % Index of start of activation
      END_ACT_F=activ_index(length(activ_index)); % Index of end of activation
      INDEX_DETREND=zeros(RUNLENGTH_F,1); % Initialisation of vector specifying location 
	    			          %  of detrending frames for current run.
      if (exist('TR')~=1), TR=0; end;     % Initialise variable with default - No. of seconds
	  				  %  per frame ('Tr time'). Allows use of global
					  %  variable TR (if defined from load window)
		
      MIN_GAP_DECAY_S=5;  % Minimum recommended no. of seconds between 
			  %  end of activation and start of detrend
			  %  window to allow for haemodynamic decay
			  % <<<<< You may change this variable if >>>>>>
                          % <<<<< you require a shorter or longer >>>>>>
                          % <<<<< minimum.                        >>>>>>

      MIN_GAP_DECAY_F=0; % Initialise
      if (TR~=0), MIN_GAP_DECAY_F=ceil(MIN_GAP_DECAY_S/TR), end; % Same value in frames
      % ==================== END OF INITIALISATION ========================

      % Initial update of fields
      eval(UpdateAllFields);
      
      % ==== Place all variables into user data structure ========== %
      detrendwindata.detrendlog = DETREND_LOG;
      detrendwindata.winwidthf = WINWIDTH_F;
      detrendwindata.winwidths = WINWIDTH_S;
      detrendwindata.postgapf = POSTGAP_F;
      detrendwindata.postgaps = POSTGAP_S;
      detrendwindata.winerror = WIN_ERROR;
      detrendwindata.runlengthf = RUNLENGTH_F;
      % detrendwindata.runlengths = RUNLENGTH_S;
      detrendwindata.numruns = NUM_RUNS;
      detrendwindata.tr = TR;
      detrendwindata.beginactf = BEGIN_ACT_F;
      % detrendwindata.beginacts = BEGIN_ACT_S;
      detrendwindata.endactf = END_ACT_F;
      % detrendwindata.endacts = END_ACT_S;
      detrendwindata.mingapdecayf = MIN_GAP_DECAY_F;
      detrendwindata.mingapdecays = MIN_GAP_DECAY_S;
      detrendwindata.currentindex = CURRENT_INDEX;
      detrendwindata.indexdetrend = INDEX_DETREND;
      detrendwindata.fullindexdetrend = FULL_INDEX_DETREND;
      set(gcf,'userdata',detrendwindata); 
      % ================= End set variables ========================= % 
      
    elseif command == 1 
      %disp('buttonClose selected.') 

      % Update the variable database with the current values
      eval(UpdateVariableDB);
      
      % Now close windows...
      close(findobj(get(0,'children'),'flat','tag','lyngby_ui_preproc_detrend'));
      if (findobj(get(0,'children'),'flat','tag','lyngby_ui_preproc_dtplot')),
	    lyngby_ui_preproc_dtplot(1);
      end;

    elseif command == 2 
      %disp('buttonApply selected.') 
      % This 'applies' the detrend pre-processing if it is selected.
      % The log string is updated respectively. 
      % The window is then closed, and the logstring written into
      % the main pre-processing window's log-box.
      
      lyngby_log('Calculating linear detrending...');
      
      %% The actual detrend algorithm
      if WIN_ERROR==0,
	  % ========== Detrend alg. a la Cyril Goutte ============ %
	  Pos=1;             % Position within the entire time-series.
	  T=RUNLENGTH_F;     % Length of a single run, after TIME_MASK has been applied
	  T1=BEGIN_ACT_F;    % Start of activation within TIME_MASKED run
	  T2=END_ACT_F;      % End of activation within TIME_MASKED run
	  dT=WINWIDTH_F;     % Length of detrend window
	  
	  % Create link to Paradigm instead of using explicit referencing?
	  % paradigm=zeros(T,1);             % activation reference function
	  % paradigm(T1:T2)=ones(T2-T1+1,1); % active period
	  
	  index_detrend=zeros(T,1);                % Create ref fn for detrend
	  index_detrend((T1-dT+1):T1)=ones(dT,1);  %  - 1st ref period
	  index_detrend((T-dT+1):T)=ones(dT,1);    %  - 2nd period
	  
	  
	  % Repeat for the number of runs in the time-series
	  if ((exist('NUM_RUNS')~=1)&(NUM_RUNS~=0)),
	    num=NUM_RUNS;
	  else
	    % Calculate from R
	    num=max(R);
	    if ((length(R)/length(find(R==1))) ~= num)
	      % All runs are not the same length (only a rough check)
	      lyngby_ui_message('Cannot do detrend unless all runs are the same length!');
	      num=0;
	    end;
	  end

	  wb_handle=waitbar(0, 'Calculating Linear Detrending - please wait');
	  for r=1:num
	    
	    % Create index reference function
	    xcoor(1:dT)=(T1-dT+1):T1;
	    xcoor((dT+1):(2*dT))=(T-dT+1):T;
	    
	    % Extract data to be detrended into the working matrix Xr (i.e.X for this run)
	    if ((exist('XN')~=1)&(XN~=0)),
	      % Extract data for present run from already preprocessed dataset
	      Xr=XN((Pos:Pos+T-1),:);  
	    else
	      % Extract data for present run from main dataset
	      Xr=X((Pos:Pos+T-1),:); 
	    end
	    
	    % Extract the relevant part of the timeseries
	    Xd=Xr(find(index_detrend==1),:)'; 
	    
	    % Calculate trend for this run
	    x_mean=mean(xcoor); 
	    x_var=std(xcoor);
	    x_var=x_var.*x_var;
	    tx_mean=Xd*xcoor'/(2*dT);
	    t_mean=mean(Xd')';
	    alf=(tx_mean -t_mean*x_mean)/x_var;
	    beta=t_mean - alf*x_mean;
	    Xtrend=alf*(1:T)+beta*ones(1,T);
	    
	    % Subtract trend from dataset and replace into original data
	    Xn=Xr-Xtrend';
	    Xdetrend((Pos:Pos+T-1),:)=Xn;
	    
	    % Update position marker
	    Pos=Pos+T;
	    
	    % Update waitbar
	    waitbar(r/num, wb_handle);
	  end

	  % Remove waitbar window after a brief pause
	  waitbar(1, wb_handle, 'Linear Detrending - Finished!'); 
	  pause(1); 
	  close(wb_handle);
	  
	  % Variable for viewing results: (possibly) centered data,
	  % but before detrending was applied  
	  PP_LDT_XN_pre_LDT=XN;  
	  
	  % Create new linear-detrended dataset
	  XN=Xdetrend; 

	  % ======= END DETREND ALG =========== %

	  %% Want to store detrend variables for viewing, if required....
	  [rXN,cXN]=size(XN);
	  mean_image=mean((X-XN),1);
	  PP_LDT_TREND_N=(X-XN)-ones(rXN,1)*mean_image; % Zero-mean version for plotting		    
	  PP_LDT_RUN=R;             % Run variable
			    
 
	  % Update the log-box in the main pre-processing window
	  DETREND_LOG = strvcat(DETREND_LOG, '  Parameters used were:- ');		
	  DETREND_LOG = strvcat(DETREND_LOG, sprintf('   Minimum post activation gap reqd = %5.2f seconds',MIN_GAP_DECAY_S));
	  DETREND_LOG = strvcat(DETREND_LOG, sprintf('   TR = %5.2f seconds/frame',TR));		
	  DETREND_LOG = strvcat(DETREND_LOG, '   Detrend window width = ');		
	  DETREND_LOG = strvcat(DETREND_LOG, sprintf('     %d Frames (%5.2f seconds)',WINWIDTH_F, WINWIDTH_S));		
	  DETREND_LOG = strvcat(DETREND_LOG, '   Post activation gap = ');		
	  DETREND_LOG = strvcat(DETREND_LOG, sprintf('     %d Frames (%5.2f seconds)',POSTGAP_F, POSTGAP_S));		
	  DETREND_LOG = strvcat(DETREND_LOG, ' Linear detrending finished.');		
	  lyngby_ui_preproc('UpdateLog', DETREND_LOG); 
      else
          % Detrend windows are invalid
          lyngby_ui_message('Cannot apply the detrending routine with the current parameters!!');
      end;
      

      
      % Update the variable database with the current values
      eval(UpdateVariableDB);
      
      lyngby_log('Linear detrending finished!');

    elseif command == 3 
      %disp('buttonHelp selected.') 

      helpwin('lyngby_ui_preproc_detrend')
      
    elseif command == 4 
        %disp('editTr selected.')
        % Check if entered Tr number makes sense
        Tr = sscanf(get(editTr,'string'),' %f');
        not_ok = 1;
        TR=0;

        if (prod(size(Tr)) == 1),
            if Tr>=0.01 & Tr<100,
                % Tr must be between a hundreth of a second, and 100
                % seconds - only a rough check...
                set(editTr,'userdata', Tr);
                s = sprintf('%f', Tr);
                not_ok = 0;
                TR=Tr;
            end
        end

        if not_ok,
            % Clear TR
            TR=0;
            s='0';
        end 
        set(editTr,'string',s);
        
        % Now update other variables, and check if all parameters are still valid. Only TR and WINWIDTH_F stay the same.
        WIN_ERROR=0;
        POSTGAP_F=RUNLENGTH_F-END_ACT_F-WINWIDTH_F;  % No of frames between end of activation and start of detrend window
        if (TR~=0), 
            MIN_GAP_DECAY_F=ceil(MIN_GAP_DECAY_S/TR);
            POSTGAP_S=POSTGAP_F*TR;
            if (WINWIDTH_F~=0), 
                WINWIDTH_S = TR*WINWIDTH_F; 
            else
                WINWIDTH_S=0;
            end;
            if ((POSTGAP_S<MIN_GAP_DECAY_S)|(POSTGAP_F<0)),   % Checks for too-small decay gap with new TR
                eval(UpdateSmallGap);
            end;
        else
            lyngby_ui_message('Cannot calculate minimum no. of frames required after the activation without a TR');
            MIN_GAP_DECAY_F=0;              
            POSTGAP_S=0;
            WINWIDTH_S=0;
            WIN_ERROR=1;
        end;
        preactivationspace=BEGIN_ACT_F;                              % Space available before activation
        postactivationspace=RUNLENGTH_F-END_ACT_F-MIN_GAP_DECAY_F;   % Space available after activation
        if preactivationspace<WINWIDTH_F,                            % Checks size of window before activation
            eval(UpdateBigFrontWindow);
            WIN_ERROR=1;
        end;
        if postactivationspace<WINWIDTH_F,      % Checks size of window after activation
            eval(UpdateBigEndWindowTR);
            WIN_ERROR=1;
        end;
        if WIN_ERROR==1,
            lyngby_ui_message('Cannot set-up detrend windows with the current parameters!');
        else,
            INDEX_DETREND((BEGIN_ACT_F-WINWIDTH_F+1):BEGIN_ACT_F)=ones(WINWIDTH_F,1);
            INDEX_DETREND((RUNLENGTH_F-WINWIDTH_F+1):RUNLENGTH_F)=ones(WINWIDTH_F,1); % Calcs location of detrend windows
            indextest=INDEX_DETREND.*CURRENT_INDEX; % Create test for overlap of detrend and activation windows
            if (find(indextest)), lyngby_ui_message('Error - overlap of detrend and activation windows'); WIN_ERROR=1; end;
        end;

        % Update the variable database with the current values
        eval(UpdateVariableDB);
        
        % Update visibility of 'seconds' fields..
        eval(UpdateAllFields);

	% Check that all runs are the same (or that detrend windows are valid for all runs)
      

	% Calculate the detrend index for all runs
	if ((exist('NUM_RUNS')~=1)&(NUM_RUNS~=0)),
	  numruns=NUM_RUNS;
	else
	  % Calculate from R
	  numruns=max(R);
	  if ((length(R)/length(find(R==1))) ~= numruns), % All runs are not the same
	    lyngby_ui_message('Cannot do detrend unless all runs are the same length!');
	    numruns=0;
	  end;
	end
	if ((numruns~=0)&(length(FULL_INDEX_DETREND)==(numruns*length(INDEX_DETREND)))),
	  FULL_INDEX_DETREND=repmat(INDEX_DETREND, numruns,1);
	else
	  lyngby_ui_message('Unable to calculate detrend indices for full dataset - unequal lengths error');
	  FULL_INDEX_DETREND=0;
	end
	
	% Update the variable database with the new FULL_INDEX_DETREND
	eval(UpdateVariableDB);

	% Update the plot, if open
	
	% fig(lyngby_ui_preproc_dtplot);
	
    elseif command == 5 
        %disp('editWinWidthFrames selected.') 
        % Set variables for the detrend algorithm - Width of detrend
        % window (in frames)
        %
        winwidthf = sscanf(get(editWinWidthFrames,'string'),' %d');
        not_ok = 1;
        WINWIDTH_F=0;

        preactivationspace=BEGIN_ACT_F;                              % Space available before activation
        postactivationspace=RUNLENGTH_F-END_ACT_F-MIN_GAP_DECAY_F;   % Space available after activation
	maxwinwidth=min(preactivationspace,postactivationspace);
	
        if (prod(size(winwidthf)) == 1),
            if ((winwidthf>=1) & (winwidthf<=maxwinwidth)),
                % Window width must be integer value, and of reasonable size.
                set(editWinWidthFrames,'userdata', winwidthf);
                s = sprintf('%d', winwidthf);
                not_ok = 0;
                WINWIDTH_F=winwidthf;
            end
        end
        
	if not_ok,
	  % Clear WINWIDTH_F
	  if maxwinwidth<=0,
	    lyngby_ui_message([ ...
		  'It seems as if you cannot setup linear ' ...
		  'detrending windows with your data - ' ...
		  'maybe your TR, or the gaps on either side ' ...
		  'of the activation, are too small. The ' ...
		  'window width has been set to zero.' ...
		  ]);
	      WINWIDTH_F=0;
	      s='0';
	    else
	      WINWIDTH_F=maxwinwidth;
	      s=sprintf('%d', maxwinwidth);
	      lyngby_ui_message([ ...
		    'Detrend window needs to be a (reasonable) non-zero integer' ...
		    ' number of frames. If the detrend' ...
		    ' window is too large, it will not fit into the' ...
		    ' gaps either side of the activation, and not allow'...
		    ' enough time after the activation for any response'...
		    ' to die away. It has been set to the'...
		    ' maximum possible for the given TR.' ...
		    ]);
	    
	    end 
	end

        set(editWinWidthFrames,'string',s);
        
        % Now update other variables, and check if all parameters are still valid. Only TR and WINWIDTH_F stay the same.
        % Need to also check that windows fit within the run, and the gaps either side of the activation, and that the
        % gap between the end of activation and the start of the second detrend window is not too small (requires a TR)

        WIN_ERROR=0;
        POSTGAP_F=RUNLENGTH_F-END_ACT_F-WINWIDTH_F;  % No of frames between end of activation and start of
                                                     %  detrend window (Can be zero if TR is very long, though
                                                     %  this is unlikely for an fMRI experiment
        if (TR~=0), 
            MIN_GAP_DECAY_F=ceil(MIN_GAP_DECAY_S/TR);
            POSTGAP_S=POSTGAP_F*TR;
            if (WINWIDTH_F~=0), % i.e. passed test above
                WINWIDTH_S = TR*WINWIDTH_F; 
            else
                WINWIDTH_S=0;
            end;
            if ((POSTGAP_S<MIN_GAP_DECAY_S)|(POSTGAP_F<0)),   % Checks for too-small decay gap with new TR
                eval(UpdateSmallGap);
            end;
        else
            lyngby_ui_message('Cannot calculate minimum no. of frames required after the activation without a TR');
            MIN_GAP_DECAY_F=0;              
            POSTGAP_S=0;
            WINWIDTH_S=0;
            WIN_ERROR=1;
        end;

        if WIN_ERROR==1,
            lyngby_ui_message('Cannot set-up detrend windows with the current parameters!');
        end;

        % Calcs location of detrend windows
	INDEX_DETREND=zeros(RUNLENGTH_F,1); % Reset first
	INDEX_DETREND((BEGIN_ACT_F-WINWIDTH_F+1):BEGIN_ACT_F)=1;
	INDEX_DETREND((RUNLENGTH_F-WINWIDTH_F+1):RUNLENGTH_F)=1; 
	indextest=INDEX_DETREND.*CURRENT_INDEX; % Create second test for overlap of detrend and activation windows
	if (find(indextest)), lyngby_ui_message('Error - overlap of detrend and activation windows'); WIN_ERROR=1; end;
        

	% Update the variable database with the current values
	eval(UpdateVariableDB);

	% Update fields with new calculated values, and test for validity
	eval(UpdateAllFields);	

	% Check that all runs are the same (or that detrend windows
	% are valid for all runs) and calculate the index of detrend
	% frames for all the runs
          
	% Calculate the detrend index for all runs
	if ((exist('NUM_RUNS')~=1)&(NUM_RUNS~=0)),
	  numruns=NUM_RUNS;
	else
	  % Calculate from R
	  numruns=max(R);
	  if ((length(R)/length(find(R==1))) ~= numruns), % All runs are not the same
	    lyngby_ui_message('Cannot do detrend unless all runs are the same length!');
	    numruns=0;
	  end;
	end
	if ((numruns~=0)&(length(FULL_INDEX_DETREND)==(numruns*length(INDEX_DETREND)))),
	  FULL_INDEX_DETREND=repmat(INDEX_DETREND, numruns,1);
	else
	  lyngby_ui_message('Unable to calculate detrend indices for full dataset - unequal lengths error');
	  FULL_INDEX_DETREND=0;
	end
	
	% Update the variable database with the new FULL_INDEX_DETREND
	eval(UpdateVariableDB);
	
	% Update the plot, if open
	% lyngby_ui_preproc_dtplot(1000);
      
    elseif command == 6 
      %disp('textWinWidthSeconds selected.') 
      % Not active in this version 
      
    elseif command == 7 
      %disp('textDecayGapFrames selected.') 
      % Not active in this version 
      
    elseif command == 8 
      %disp('textDecayGapSeconds selected.') 
      % Not active in this version 
      
    elseif command == 9 
      %disp('buttonCallPlot selected.') 
      % Call paradigm/masking type window...
      lyngby_ui_preproc_dtplot;
      
      % Update the variable database with the current values
      eval(UpdateVariableDB);

      % Temp addition of update for debugging...
      eval(UpdateAllFields);	

    elseif command == 10
      %disp('buttonViewResults selected.') 
      % Allow viewing of results from this window instead of from
      % main preprocessing window. This means calculation of the
      % extra variables required for the plots are only done when
      % required, thus saving memory

      if (exist('PP_LDT_TREND_N') & exist('PP_LDT_RUN'))&(~isempty(PP_LDT_TREND_N)&~isempty(PP_LDT_RUN)),
	lyngby_uis_pp_detrend_v;
	% disp('Calling new viewing routine');
      else
	  lyngby_ui_message(['The data has not been detrended yet!']);
      end

            
    elseif command == 100
      % Toggle the state of the Tooltips help (on/off)
      eval(ToggleTooltips);

    else 
      error('Error: lyngby_ui_preproc_detrend.m called with incorrect command.') 
    end
    
    
