% DEFINE_BIFF script to define the known BIFF chunk types
%
% This function should not be called separately, it is intended to
% be used from withing read_biff and write_biff.
%
% See also READ_BIFF, WRITE_BIFF

% Copyright (C) 2000, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
%    FieldTrip is free software: you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation, either version 3 of the License, or
%    (at your option) any later version.
%
%    FieldTrip is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$

CAT_.desc = {'CAT ', 'cat', 'unknown'};
LIST.desc = {'LIST', 'list',    'unknown'};
BIFF.desc = {'BIFF', 'biff',    'group'};

BIFF.SEMG.desc = {'SEMG', 'semg',   'group'};

BIFF.SEMG.VERS.desc = {'VERS', 'version',       'group'};
BIFF.SEMG.DINF.desc = {'DINF', 'data_info',     'group'};
BIFF.SEMG.EXPI.desc = {'EXPI', 'experiment',        'group'};
BIFF.SEMG.MEAS.desc = {'MEAS', 'measurement',       'group'};
BIFF.SEMG.SGRD.desc = {'SGRD', 'semggrid',      'group'};
BIFF.SEMG.PATI.desc = {'PATI', 'patient',       'group'};

BIFF.SEMG.VERS.ID__.desc = {'ID  ', 'id',       'string'};
BIFF.SEMG.VERS.LIC_.desc = {'LIC ', 'license',      'string'};

BIFF.SEMG.DATI.CHAN.desc = {'CHAN', 'unknown'       'unknown'};
BIFF.SEMG.DATI.MODE.desc = {'MODE', 'unknown'       'unknown'};
BIFF.SEMG.DATI.TYPE.desc = {'TYPE', 'unknown'       'unknown'};
BIFF.SEMG.DATI.FS__.desc = {'FS  ', 'unknown'       'unknown'};
BIFF.SEMG.DATI.LABL.desc = {'LABL', 'unknown'       'unknown'};
BIFF.SEMG.DATI.UNIT.desc = {'UNIT', 'unknown'       'unknown'};
BIFF.SEMG.DATI.FILT.desc = {'FILT', 'unknown'       'unknown'};

BIFF.SEMG.EXPI.NAME.desc = {'NAME', 'name',     'string'};
BIFF.SEMG.EXPI.EXAM.desc = {'EXAM', 'examination',  'string'};
BIFF.SEMG.EXPI.EXRC.desc = {'EXRC', 'exercise',     'string'};
BIFF.SEMG.EXPI.RPHS.desc = {'RPHS', 'ref_physician',    'string'};
BIFF.SEMG.EXPI.DATE.desc = {'DATE', 'date',     'unknown'};
BIFF.SEMG.EXPI.TIME.desc = {'TIME', 'time',     'unknown'};

BIFF.SEMG.MEAS.TIME.desc = {'TIME', 'time',     'string'};
BIFF.SEMG.MEAS.ORFN.desc = {'ORFN', 'filename',     'string'};
BIFF.SEMG.MEAS.MUSC.desc = {'MUSC', 'muscle',       'string'};
BIFF.SEMG.MEAS.SIDE.desc = {'SIDE', 'side',     'unknown'};
BIFF.SEMG.MEAS.FNUM.desc = {'FNUM', 'filenumber',   'unknown'};
BIFF.SEMG.MEAS.TEMP.desc = {'TEMP', 'temperature',  'unknown'};
BIFF.SEMG.MEAS.ANOT.desc = {'ANOT', 'annotation',   'string'};
BIFF.SEMG.MEAS.FORC.desc = {'FORC', 'force',        'string'};

BIFF.SEMG.SGRD.NPD_.desc = {'NPD ', 'npd',      'unknown'};
BIFF.SEMG.SGRD.NML_.desc = {'NML ', 'nml',      'unknown'};
BIFF.SEMG.SGRD.IED_.desc = {'IED ', 'ied',      'unknown'};
BIFF.SEMG.SGRD.FIBD.desc = {'FIBD', 'fibre_dir',    'unknown'};
BIFF.SEMG.SGRD.POS_.desc = {'POS ', 'tle_pos',      'unknown'};
BIFF.SEMG.SGRD.CABL.desc = {'CABL', 'cable_pos',    'unknown'};
BIFF.SEMG.SGRD.GRID.desc = {'GRID', 'grid',     'int16vec'};

BIFF.SEMG.PATI.UPID.desc = {'UPID', 'unique_id',    'unknown'};
BIFF.SEMG.PATI.GEND.desc = {'GEND', 'gendre',       'unknown'};
BIFF.SEMG.PATI.BDAT.desc = {'BDAT', 'birthdate',    'unknown'};
BIFF.SEMG.PATI.HPID.desc = {'HPID', 'hospital_id',  'unknown'};
BIFF.SEMG.PATI.ANAM.desc = {'ANAM', 'anamnesis',    'unknown'};


%
%M-file for compiling and linking the FGI source files
%
%Date: 01-06-2000
%Copyright (c) 2000 R.Heil, C. L. Wauters
%SYNTAX buildall;
%
%
%DESCRIPTION File for easily compiling and linking the FGI source files.
%
%INPUT The user is asked to input the source directory and output directory
%
%EXAMPLE:
%buildall;
%

INC = '-Iy:\software\dt\fgsdk32\include';
INC52='-Iy:\software\dt\fgsdk32\include\dt3152';
INC57='-Iy:\software\dt\fgsdk32\include\dt3157';
INCCO='-Iy:\software\dt\fgsdk32\include\colorsdk';
LIB = 'y:\software\dt\fgsdk32\lib\olimg32.lib y:\software\dt\fgsdk32\lib\olfg32.lib';

disp(' ');
%SOURCE = input('Enter the source directory (example: g:\\sourcedir ) -> ','s');
SOURCE = '..\Src';
%OUTDIR = input('Enter the output directory (example: g:\\matlab ) -> ','s');
OUTDIR = '..\Bin';
SOURCE = strcat(SOURCE,'\\');

disp(' ');
disp('Building FGI source files');
disp(' ');

disp('Compiling setfg');
com = strcat(SOURCE,'setfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling getfg');
com = strcat(SOURCE,'getfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling loadfg');
com = strcat(SOURCE,'loadfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling resetfg');
com = strcat(SOURCE,'resetfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling grabfg');
com = strcat(SOURCE,'grabfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling isopenfg');
com = strcat(SOURCE,'isopenfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,'-outdir',OUTDIR)

disp('Compiling gethandlefg');
com = strcat(SOURCE,'gethandlefg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,'-outdir',OUTDIR)

disp('Compiling openfg');
com = strcat(SOURCE,'openfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling closefg');
com = strcat(SOURCE,'closefg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,LIB,'-outdir',OUTDIR)

disp('Compiling mainfg');
com = strcat(SOURCE,'mainfg.c');
mex(com,'-O',INC,INC52,INC57,INCCO,'-outdir',OUTDIR)


%% The Class poleFigure
%
%%
%


function [ boolout ] = istiffcapella( filename )
%ISTIFFCAPELLA Test if data is Capella TIFF format
%
% Written by: Wade Schwartzkopf, NGA/IDT
%
% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////

tags = read_tiff_tags(filename);
boolout = isfield(tags{1}, 'Software') && strncmpi(tags{1}.Software,'Capella',7);

end

% //////////////////////////////////////////
% /// CLASSIFICATION: UNCLASSIFIED       ///
% //////////////////////////////////////////


%CODINGCONVENTIONS specify coding conventions for MALIMPA m-files
%
%   General:
%
%   This file specifies coding convention for future files. Some files may
%   not necessarily follows the requirements, as they were created before
%   conventions.
%
%   Name of functions:
%
%   Java convention for file names must be used:
%   - Each function name must be written in lower case, using english
%       denomination.
%   - For compound function names, the first letter of each component after
%       the first one is capitalized.
%       Ex: 'distancePointPlane'.
%
%   Other convention should be used to avoid name conflicts:
%   - For function used as image filters, prefix 'im' may be used. Ex :
%       'imDirFilter'.
%   - For functions which work on a complex data type, the name of the data
%       type should be used as a prefix of the function name.
%       Ex: functions working on polygons have a prototype on the form
%       'polygonLength', 'polygonArea'...
%   - Functions working with geometrical primitives can use a suffix for
%       indicating the dimension of application.
%       Ex: 'distancePointLine3d'.
%       This convention was not used for the beginning of the library
%       development, but new functions will try to conform to it.
%
%   Function header:
%
%   - First line of documentation must contain the name of the function,
%   followed by a short description. Name and function may be separated by
%   colon. Name must be capitalized, without punctuation before
%   description (to remain valid with matlab documenbtation tools).
%   Ex:   'SLICER Interactive visualization of 3D images'
%
%   - Main part of header describes usage of function/script with various
%   parameters. Function name should be the real name. Variables names
%   should be capitalized. This does not follow matlab's standard, but
%   allows to copy-paste pieces of code.
%   Ex: 'RES = myBasicFunction(PARAM1, PARAM2, OPTION);'
%
%   - The description of each calling syntax should be written using
%   conjugated verbs.
%
%   - End of header should contain name of author, with date of creation.
%   It may also contains author affiliation (company ...), and date of last
%   revision.
%
%
%   Library Organization:
%
%   The principle is to gather functions which share a similar domain of
%   application. Ex: image processing filters, geometry functions...
%   It seems better to have one level of complexity for the directory
%   structure.
%
%   However, it could be clearer to create specific subdirectories for
%   functions which operate on complex data (such as polygons, or special
%   types of curves). This allows to add a Contents file which describes
%   the model used by functions.
%
%
%   Function code:
%
%   - Please comment the code ! For algorithmic parts, as much comments as
%   code is a good start ...
%   - Indentation level should be marked by four space characters.
%
%
%   Tips & Tricks:
%
%   - The use of '...' at the end of a line can cause compatibility
%   problems from Linux to Windows.
%   - matlab help uses the file 'Contents.m', not 'contents.m' !
%
%
%   ---------
%
%   author : David Legland
%   INRA - TPV URPOI - MIA MathCell
%   created the 23/03/2005
%

%   HISTORY
%   05/03/2007 add convention for datatype prefix for function names, and
%       library organization

help codingConventions;


function [go,s1]=fmri_loc1_checkDataTypesForGLM(fid,dataTYPES)
% Usage: checkDataTypesForGLM(fid)
%
% Fid = file id for error log text file
%
% Function for use in GLM batch script context.
% 1. Find 'MotionComp_RefScan1' dataTYPE #
% 2. Find 'loloc_run1' scan # for MC dataTYPE
%
% If conditions not met (e.g., EXACT STRING MATCHES for 1,2,3), will report
% error and return, skipping that subject, and set GO flag to 0.
%
% DY 06/08/2008
% AL 11/08 Modified for loc1 GLM

if notDefined('fid')    fid=1;   end
go=1; % flag that is set to 0 if any errors in datatype fields
s1=struct;

% Names for particular dataTYPES / scans
mcName = 'MotionComp_RefScan1';
lo1Name = 'loloc_run1';

% Only set the mc_dt variable if there is one MC dataTYPE, else log the
% person and find some way to deal with it (for now, we RETURN)
% NOTE: Golijeh usually runs the LO localizer scan first, so these
% scans should always use the MotionComp_RefScan1 dataTYPE.
mcs = zeros(1,length(dataTYPES));
mcs=strcmp({dataTYPES.name},mcName);
if sum(mcs)==1
    mc_dt=find(mcs==1);
    fprintf(fid,'Found %s for dataTYPES %d\n',mcName, mc_dt);
    fprintf('Found %s for dataTYPES %d\n',mcName, mc_dt);
else
    fprintf(fid,'Error: Found %d %s dataTYPES, skipping... \n\n',sum(mcs),mcName);
    fprintf('Error: Found %d %s dataTYPES, skipping... \n\n',sum(mcs),mcName);
    go=0;
    return
end

% Find scans with "loloc_run#" in the annotation field
lo1scans=zeros(1,length(dataTYPES(mc_dt).scanParams));
lo1scans=strcmp({dataTYPES(mc_dt).scanParams.annotation},lo1Name);
if sum(lo1scans)==1
    lo_scan1=find(lo1scans==1);
    fprintf(fid,'Found %s for dataTYPES %d scan %d \n',lo1Name, mc_dt, lo_scan1);
    fprintf('Found %s for dataTYPES %d scan %d\n',lo1Name, mc_dt, lo_scan1);
else
    fprintf(fid,'Error: Found %d %s scans, skipping... \n\n',sum(lo1scans),lo1Name);
    fprintf('Error: Found %d %s scans, skipping... \n\n',sum(lo1scans),lo1Name);
    go=0;
    return
end

% Find parfile and scangroup assignments for those scans
% First check if these fields exist. If they do not, print the relevant
% error to file and exit, setting go=0.

if (~isfield(dataTYPES(mc_dt).scanParams(lo_scan1),'parfile')) | ...
        (~isfield(dataTYPES(mc_dt).scanParams(lo_scan1),'scanGroup'))
    fprintf(fid,'Error: Parfile and/or scanGroup fields do not exist for dataTYPES %d... \n\n',mc_dt);
    fprintf('Error: Parfile and/or scanGroup fields do not exist for dataTYPES %d... \n\n',mc_dt);
    go=0;
    return
end

parfile1=dataTYPES(mc_dt).scanParams(lo_scan1).parfile;
scangroup1=dataTYPES(mc_dt).scanParams(lo_scan1).scanGroup;
fprintf(fid,'Parfile for %s: %s \n',lo1Name, parfile1);
fprintf('Parfile for %s: %s \n',lo1Name, parfile1);
fprintf(fid,'ScanGroup for %s: %s \n',lo1Name, scangroup1);
fprintf('ScanGroup for %s: %s \n',lo1Name, scangroup1);

% Set s1 struct fields
s1.mc=mc_dt;
s1.scan=lo_scan1;
s1.parfile=parfile1;
s1.scangroup=scangroup1;

return


function varargout = rmEditStimParams(varargin)
% RMEDITSTIMPARAMS M-file for rmEditStimParams.fig
%      RMEDITSTIMPARAMS, by itself, creates a new RMEDITSTIMPARAMS or raises the existing
%      singleton*.
%
%      H = RMEDITSTIMPARAMS returns the handle to a new RMEDITSTIMPARAMS or the handle to
%      the existing singleton*.
%
%      RMEDITSTIMPARAMS('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RMEDITSTIMPARAMS.M with the given input arguments.
%
%      RMEDITSTIMPARAMS('Property','Value',...) creates a new RMEDITSTIMPARAMS or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before rmEditStimParams_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to rmEditStimParams_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% NOTE: You can also pass in a view structure as the first option:
%	rmEditStimParams(view, [options...]).   (ras, 01/09)
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help rmEditStimParams

% Last Modified by GUIDE v2.5 16-Jan-2009 16:56:08

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @rmEditStimParams_OpeningFcn, ...
                   'gui_OutputFcn',  @rmEditStimParams_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
return;

% --- Executes just before rmEditStimParams is made visible.
function rmEditStimParams_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
%
% The key subroutines are:
% 1. rmEditStimParams_OpeningFcn (this one), which initializes values in
% the UI window
% 2. paramsToWindow: writes values from the parameters to the UI window
% 3. paramsFromWindow: writes values from the UI window to the parameters
% 4. btnDone_Callback: writes values to parameters and then to vista view

% Choose default command line output for rmEditStimParams
handles.output = hObject;

%% get the view associated with these parameters
% (ras, 01/09, change from original): does not require that you're using a
% global VOLUME view. Should allow inplanes and hidden view structures. So,
% we allow you to pass the view in as the first argument, if it's a hidden
% view. Otherwise, finds the currently-selected view.
if ~isempty(varargin) & isstruct(varargin{1}) & isfield(varargin{1}, 'viewType')
	handles.vw = varargin{1};
else
	handles.vw = getCurView; % does not always get current view because it is order dependent
end

handles.dt = viewGet(handles.vw, 'currentdatatypestructure');

% Put values into the window.  We first check the stimulus
% parameterization for the currently loaded rm model.
sParams = viewGet(handles.vw,'rmStimParams');

%  If there is no currently loaded model, we try to get the values from the
%  dataTYPES.
if isempty(sParams), sParams = dtGet(handles.dt, 'rmParams'); end

% We enforce the stimulus parameters organization. If no values were found
% in a current model or in the dataTYPES, we put in defaults. If values
% were found, we check that all necessary fields are present, and that
% unrecognized fields are removed. Older computed data such as 'images' and
% 'images_org' are deleted here.  We create the new images and related
% fields when we push the Done button.
sParams = rmCreateStim(handles.vw,sParams);

% Store the current stimulus parameters
handles.sParams = sParams;

% Initialize the scan slider
nScans = length(sParams);
setScanSlider(hObject, nScans);

% We need to a separate variable which will tell us the previous scan after
% the slider or edit box are changed clicked. Since we always initialize at
% scan 1, we set prior scan to 1 when we open the GUI.
handles.priorScan = 1;

% Identify the number of scans in the session
% set(handles.txtScanNum,'String',sprintf('Scan (%d)',nScans));
set(handles.editNumScans,'String',num2str(nScans));
guidata(hObject,handles);

% Refresh the UI using the fields in the stimulus parameters (sParams)
whichScan = 1; paramsToWindow(hObject,whichScan);

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes rmEditStimParams wait for user response (see UIRESUME)
% uiwait(handles.rmEditStimParams);
return;

% --- Outputs from this function are returned to the command line.
function varargout = rmEditStimParams_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;
return;

% - Refresh the window using current values of stimulus parameters
function paramsToWindow(hObject,whichScan)
% Copy parameters from the view structure into the window

% Get current state of handles and stimulus parameters
handles = guidata(hObject);
thisParams = handles.sParams(whichScan);

% The popupClass must be set before calling this routine
refreshImagePopups(hObject,whichScan);

% Set the edit boxes
set(handles.editRadius,'String',num2str(thisParams.stimSize));
set(handles.editWidth,'String',num2str(thisParams.stimWidth));
set(handles.editStartPhase,'String',num2str(thisParams.stimStart));
set(handles.editCycles,'String',num2str(thisParams.nCycles));
set(handles.editMeanBlocks,'String',num2str(thisParams.nStimOnOff));
set(handles.editRep,'String',num2str(thisParams.nUniqueRep));
set(handles.editDetrend,'String',num2str(thisParams.nDCT));
set(handles.editRemoved,'String',num2str(thisParams.prescanDuration));
set(handles.editFrames,'String',num2str(thisParams.nFrames));
set(handles.editInterval,'String',num2str(thisParams.framePeriod));

% Check boxes
if ~checkfields(thisParams, 'fliprotate'), thisParams.fliprotate = [0 0 0]; end
flip = thisParams.fliprotate;
if length(flip) < 3, thisParams.fliprotate = padarray(flip,3-length(flip), 'post'); end
set(handles.cboxLR,'Value',thisParams.fliprotate(1));
set(handles.cboxUD,'Value',thisParams.fliprotate(2));
set(handles.cboxCCW,'Value',thisParams.fliprotate(3));

guidata(hObject,handles);

return;

% - Should be a separate utility function
function ii = getPopupValue(h,target)
% Given a handle to a popup, h, find the value

str = get(h,'String');
if ~iscell(str)  % Only one term
    if strcmpi(str,target), ii = 1; return; end
else
    for ii=1:length(str)
        if strcmpi(str{ii},target)
            return;
        end
    end
end

% Returns a safe value, but maybe it should be null?
ii = 1;

% if strcmpi(target,'none'), return;
% else fprintf('Target string [%s] not found\n',target);
% end

return;

% - Refresh the parameters using current values window objects
function paramsFromWindow(hObject,handles,whichScan)

% Current parameter values
thisParams = handles.sParams(whichScan);

% Update the values from the handles
% Copy parameters from the view structure into the window

% Spatial grouping
%
classes = get(handles.popupClass,'String');
thisParams.stimType = classes{get(handles.popupClass,'value')};

thisParams.stimSize = str2double(get(handles.editRadius,'String'));
thisParams.stimWidth = str2double(get(handles.editWidth,'String'));
thisParams.stimStart = str2double(get(handles.editStartPhase,'String'));

% An integer that defines in/out or cw/ccw
thisParams.stimDir = get(handles.popupDirection,'value') - 1;

thisParams.nCycles         = str2double(get(handles.editCycles,'String'));
thisParams.nStimOnOff      = str2double(get(handles.editMeanBlocks,'String'));
thisParams.nUniqueRep      = str2double(get(handles.editRep,'String'));
thisParams.nDCT            = str2double(get(handles.editDetrend,'String'));

% Timing grouping
thisParams.prescanDuration = str2double(get(handles.editRemoved,'String'));
thisParams.nFrames         = str2double(get(handles.editFrames,'String'));
thisParams.framePeriod     = str2double(get(handles.editInterval,'String'));

% Timing grouping
classes = get(handles.popupHRFModel,'String');
v = get(handles.popupHRFModel,'value');
thisParams.hrfType = classes{v};

% These are the Boynton and SPM HRF parameters and now an impulse HRF
% We are guessing that the hrfType field is used to choose between these
% two (now three) parameter sets
%
% hrfModelParams = {[1.68,3 ,2.05],[5.4,5.2 ,10.8,7.35,0.35], [1]};
% thisParams.hrfParams = hrfModelParams{v};

% Image Grouping
thisParams.fliprotate(1) = get(handles.cboxLR, 'Value');
thisParams.fliprotate(2) = get(handles.cboxUD, 'Value');
thisParams.fliprotate(3) = get(handles.cboxCCW,'Value');

classes = get(handles.popupImageFile,'String');
thisParams.imFile = classes;
if iscell(classes)
    thisParams.imFile = classes{get(handles.popupImageFile,'value')};
end

classes = get(handles.popupParamsFile,'String');
thisParams.paramsFile = classes;
if iscell(classes)
    thisParams.paramsFile = classes{get(handles.popupParamsFile,'value')};
end

classes = get(handles.popupImageFilter,'String');
thisParams.imFilter = classes;
if iscell(classes)
    thisParams.imFilter = classes{get(handles.popupImageFilter,'value')};
end

classes = get(handles.popupJitter,'String');
thisParams.jitterFile = classes;
if iscell(classes)
    thisParams.jitterFile = classes{get(handles.popupJitter,'value')};
end

% Put them back in the handles structure
handles.sParams(whichScan) = thisParams;

guidata(hObject,handles);

return;

% --- Executes on slider movement.
function sliderScan_Callback(hObject, eventdata, handles)
% We copy the data in the window to the handles.sParams entries.

% The user clicked on the slider and changed the scan to this new value
v = get(handles.sliderScan,'Value');

% make sure the value is an integer.
v = round(v);

% We update the edit box as well.
set(handles.editScan,'String',num2str(v));

% Before we clicked, we were operating on a prior scan.
% We take the parameters in the window and copy them into the parameter
% fields of that scan.
whichScan = handles.priorScan;
paramsFromWindow(hObject,handles,whichScan);
handles = guidata(hObject);

% Copy the parameters in thisParams from the new scan into the window
whichScan = v;
paramsToWindow(hObject,whichScan);

% The present becomes past
handles.priorScan=v;

guidata(hObject,handles);

return;

% --- Executes during object creation, after setting all properties.
function sliderScan_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderScan (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

return;

function editScan_Callback(hObject, eventdata, handles)
% When the edit box for scan number is changed

% Make sure we are in range
nScans = length(handles.sParams);
v = str2double(get(handles.editScan,'string')); v = min(v,nScans); v = max(1,v);

% Adjust the slider
set(handles.sliderScan,'value',v);
set(handles.editScan,'string',num2str(v));

% Move the stimulus parameter data from the window
whichScan = handles.priorScan;
paramsFromWindow(hObject,handles,whichScan);
handles = guidata(hObject);

% Copy the new parameters to the window
whichScan = v;
paramsToWindow(hObject,whichScan);

% The present becomes past
handles.priorScan=v;

guidata(hObject,handles);
return;

% --- Executes during object creation, after setting all properties.
function editScan_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editScan (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on selection change in popupClass.
function popupClass_Callback(hObject, eventdata, handles)
% Must update the popups because we may choose stimFromScan clas

whichScan = get(handles.sliderScan,'value');
paramsFromWindow(hObject,handles,whichScan)
refreshImagePopups(hObject,whichScan);

return;

% --- Executes during object creation, after setting all properties.
function popupClass_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editRadius_Callback(hObject, eventdata, handles)
return;

% --- Executes during object creation, after setting all properties.
function editRadius_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editWidth_Callback(hObject, eventdata, handles)
return;

% --- Executes during object creation, after setting all properties.
function editWidth_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editStartPhase_Callback(hObject, eventdata, handles)
% hObject    handle to editStartPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editStartPhase as text
%        str2double(get(hObject,'String')) returns contents of editStartPhase as a double

return;

% --- Executes during object creation, after setting all properties.
function editStartPhase_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editStartPhase (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on selection change in popupDirection.
function popupDirection_Callback(hObject, eventdata, handles)
% hObject    handle to popupDirection (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupDirection contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupDirection
return;

% --- Executes during object creation, after setting all properties.
function popupDirection_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupDirection (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editCycles_Callback(hObject, eventdata, handles)
% hObject    handle to editCycles (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editCycles as text
%        str2double(get(hObject,'String')) returns contents of editCycles as a double

return;
% --- Executes during object creation, after setting all properties.
function editCycles_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editCycles (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editMeanBlocks_Callback(hObject, eventdata, handles)
% hObject    handle to editMeanBlocks (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editMeanBlocks as text
%        str2double(get(hObject,'String')) returns contents of editMeanBlocks as a double
return;

% --- Executes during object creation, after setting all properties.
function editMeanBlocks_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editMeanBlocks (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editRep_Callback(hObject, eventdata, handles)
% hObject    handle to editRep (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editRep as text
%        str2double(get(hObject,'String')) returns contents of editRep as a double
return;

% --- Executes during object creation, after setting all properties.
function editRep_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editRep (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editDetrend_Callback(hObject, eventdata, handles)
% hObject    handle to editDetrend (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editDetrend as text
%        str2double(get(hObject,'String')) returns contents of editDetrend as a double
return;

% --- Executes during object creation, after setting all properties.
function editDetrend_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editDetrend (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editRemoved_Callback(hObject, eventdata, handles)
% hObject    handle to editRemoved (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editRemoved as text
%        str2double(get(hObject,'String')) returns contents of editRemoved as a double
return;

% --- Executes during object creation, after setting all properties.
function editRemoved_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editRemoved (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on button press in cboxLR.
function cboxLR_Callback(hObject, eventdata, handles)
% hObject    handle to cboxLR (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cboxLR

return;

% --- Executes on selection change in popupImageFile.
function popupImageFile_Callback(hObject, eventdata, handles)
% hObject    handle to popupImageFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupImageFile contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupImageFile
return;

% --- Executes during object creation, after setting all properties.
function popupImageFile_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupImageFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on selection change in popupParamsFile.
function popupParamsFile_Callback(hObject, eventdata, handles)
% hObject    handle to popupParamsFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupParamsFile contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupParamsFile
return;

% --- Executes during object creation, after setting all properties.
function popupParamsFile_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupParamsFile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on selection change in popupImageFilter.
function popupImageFilter_Callback(hObject, eventdata, handles)
% hObject    handle to popupImageFilter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupImageFilter contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupImageFilter
return;

% --- Executes during object creation, after setting all properties.
function popupImageFilter_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupImageFilter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on button press in cboxJitter.
function cboxJitter_Callback(hObject, eventdata, handles)
% hObject    handle to cboxJitter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cboxJitter
return;
% --- Executes on selection change in popupHRFModel.
function popupHRFModel_Callback(hObject, eventdata, handles)
% hObject    handle to popupHRFModel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupHRFModel contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupHRFModel
return;

% --- Executes during object creation, after setting all properties.
function popupHRFModel_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupHRFModel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

function editFrames_Callback(hObject, eventdata, handles)
% hObject    handle to editFrames (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editFrames as text
%        str2double(get(hObject,'String')) returns contents of editFrames as a double
return;

% --- Executes during object creation, after setting all properties.
function editFrames_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editFrames (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

return;

function editInterval_Callback(hObject, eventdata, handles)
% hObject    handle to editInterval (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editInterval as text
%        str2double(get(hObject,'String')) returns contents of editInterval as a double
return;

% --- Executes during object creation, after setting all properties.
function editInterval_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editInterval (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

% --- Executes on button press in btnCancel.
function btnCancel_Callback(hObject, eventdata, handles)
% hObject    handle to btnCancel (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close;
return;

% --- Executes on button press in btnDone.
function btnDone_Callback(hObject, eventdata, handles)
% User is finished.  Parameters from window to sParams
% Then we attach it do dataTypes and view.

whichScan  = get(handles.sliderScan,'Value');
paramsFromWindow(hObject,handles,whichScan);
handles = guidata(hObject);
paramsToVista(hObject,handles);

closereq

return;

% Copy the final set of stimulus parameters into the view and dataTypes
function paramsToVista(hObject,handles)
% Assign the new values to the view structure and dataType

% Make the current view variable (INPLANE, VOLUME) and dataTYPE accessible
mrGlobals;

handles = guidata(hObject);
handles = fileFullPath(handles);

handles.vw = viewSet(handles.vw, 'rmStimParams',handles.sParams);

% save to data types if selected
% (see discussion in the change log for this file)
hSave = findobj('Tag', 'cbox_saveToDataTYPES');
hSaveValue = get(hSave, 'Value');
if iscell(hSaveValue) % hSaveValue is a cell struct.
    hSaveValue = hSaveValue{1};
end
if hSaveValue==1
	dtNum = viewGet(handles.vw,'dtNumber');
	handles.dt = dtSet(handles.dt,'retinotopyModelParams',handles.sParams);
	dataTYPES(dtNum).retinotopyModelParams = [];
    dataTYPES(dtNum) = handles.dt;
	fprintf('Updated stored stimulus parameters in dataTYPES.\n');
	saveSession;
end

% rmLoadParameters builds the stimuli (images) and computes various things
% and puts them into the view.
handles.vw = rmLoadParameters(handles.vw);

% if this is a global variable (INPLANE, VOLUME), update the global
% variable to match this view
if strncmp(handles.vw.name, 'INPL', 4) | strncmp(handles.vw.name, 'VOLU', 4)
	updateGlobal(handles.vw);
end

return

function h = fileFullPath(h)
% Convert the file names to full paths for this session.

nScans  = length(h.sParams);
homeDir = viewGet(h.vw,'homeDir');

for ii=1:nScans

    [p,n,e] = fileparts(h.sParams(ii).imFile);
    h.sParams(ii).imFile = fullfile(homeDir,'Stimuli',[n,e]);

    [p,n,e] = fileparts(h.sParams(ii).jitterFile);
    h.sParams(ii).jitterFile = fullfile(homeDir,'Stimuli',[n,e]);

    [p,n,e] = fileparts(h.sParams(ii).paramsFile);
    h.sParams(ii).paramsFile = fullfile(homeDir,'Stimuli',[n,e]);
end

return;

function setScanSlider(hObject, nScans)

handles = guidata(hObject);

% get the current scan number
scanNum = str2num(get(handles.editScan, 'String'));

% check that it is not greater than the number of scans being set
if scanNum > nScans,
    error('Number of scans is less than the current scan number');
end

% The user clicked on the slider and changed the scan to this new value

if nScans > 1
    % Multiple scans - possibility of changing
    set(handles.sliderScan,'min',1);
    set(handles.sliderScan,'max',nScans);
    set(handles.sliderScan,'sliderStep',[1/(nScans-1) 1/(nScans-1)])
    set(handles.sliderScan,'Value',scanNum);
    set(handles.editScan,'String',num2str(scanNum));
    set(handles.sliderScan,'Visible','on');
    set(handles.editScan,'Visible','on');
else
    % Only one scan - so no possibility of changing
    set(handles.sliderScan,'min',1);
    set(handles.sliderScan,'max',1);
    set(handles.sliderScan,'Value',1);
    set(handles.sliderScan,'Visible','off');
    set(handles.editScan,'Visible','off');
end
guidata(hObject,handles);
return

% --- Executes on selection change in popupJitter.
function popupJitter_Callback(hObject, eventdata, handles)
% hObject    handle to popupJitter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupJitter contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupJitter
return;

% --- Executes during object creation, after setting all properties.
function popupJitter_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupJitter (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return;

%  --- Manage the image popup strings depending on context
function refreshImagePopups(hObject,whichScan)
% Fill fields when StimFromScan field in class
% Gray out the text when popups are irrelevant

handles = guidata(hObject);
thisParams = handles.sParams(whichScan);

% Set Class poup
switch thisParams.stimType
    case '8Bars',        v = 1;
    case 'Ring',         v = 2;
    case 'RoughBars',    v = 3;
    case 'Wedge',        v = 4;
    case 'StimFromScan', v = 5;
    case 'StimFromScan1D', v = 6;
    otherwise,
        warndlg('Unknown stimulus type')
        v = 1;
end
set(handles.popupClass,'value',v);

% Set stimulus direction popup
switch thisParams.stimDir
    case 0,  v = 1;
    case 1,  v = 2;
    otherwise,
        warndlg('Unknown direction')
        v = 1;
end
set(handles.popupDirection,'value',v);

% HRF type
switch thisParams.hrfType
    case 'one gamma (Boynton style)', v = 1;
    case 'two gammas (SPM style)',    v = 2;
    case 'impulse',                   v = 3;
    otherwise,
        warndlg('Unknown HRF model %s',thisParams.hrfType)
        v = 1;
end
set(handles.popupHRFModel,'value',v);

% Define the Stimuli directory for finding local files
sDir = fullfile(viewGet(handles.vw,'homeDir'),'Stimuli');

% Populate the pulldown strings
switch lower(thisParams.stimType)
    case {'stimfromscan','stimfromscan1d'}
        grayEditText(handles,whichScan);  % Stim from scan

        % If stimfromscan, we populate with files in the Stimuli
        % directory.

        if exist(sDir,'dir')
            % Image pulldown
            f = dir(fullfile(sDir,'*image*.mat'));
            str = cell(length(f),1);
            if ~isempty(f)
                for ii=1:length(f)
                    str{ii} = f(ii).name;
                end
                set(handles.popupImageFile,'String',str);
            end
            set(handles.txtImgFile,'foregroundcolor',[0 0 0]);

            % Image pulldown
            f = dir(fullfile(sDir,'*params*.mat'));
            str = cell(length(f),1);
            if ~isempty(f)
                for ii=1:length(f)
                    str{ii} = f(ii).name;
                end
                set(handles.popupParamsFile,'String',str);
            end
            set(handles.txtPFile,'foregroundcolor',[0 0 0]);

            % Filter definitions
            d = fullfile(mrvRootPath,'Analysis',...
                'retinotopyModel',...
                'FilterDefinitions','*.m');
            f = dir(d);
            str = cell(length(f)+1,1);
            str{1} = 'none';
            for ii=1:length(f)
                s = findstr(f(ii).name,'_');
                [p,str{ii+1},e] = fileparts(f(ii).name((s+1):end));
            end
            set(handles.popupImageFilter,'String',str);
            set(handles.txtIFilter,'foregroundcolor',[0 0 0]);
        end

    otherwise
        grayEditText(handles,whichScan);  % Not stim from scan

        % For most cases, these are not options so we gray them out
        set(handles.popupImageFile,'String','none');
        set(handles.popupImageFile,'Value',1);
        set(handles.popupParamsFile,'String','none');
        set(handles.popupParamsFile,'Value',1);
        set(handles.popupImageFilter,'String','none');
        set(handles.popupImageFilter,'Value',1);

end

% Populate the pulldown Jitter files
f = dir(fullfile(sDir,'*jitter*.mat'));
str = cell(length(f)+1,1); str{1} = 'none';
if ~isempty(f)
    for ii=1:length(f)
        str{ii+1} = f(ii).name;
    end
end
set(handles.popupJitter,'String',str);

% We set the pulldown values
bName = mrvFileNameExt(thisParams.imFile);
v = getPopupValue(handles.popupImageFile,bName);
set(handles.popupImageFile,'Value',v);

bName = mrvFileNameExt(thisParams.paramsFile);
v = getPopupValue(handles.popupParamsFile,bName);
set(handles.popupParamsFile,'Value',v);

bName = mrvFileNameExt(thisParams.imFilter);
v = getPopupValue(handles.popupImageFilter,bName);
set(handles.popupImageFilter,'Value',v);

% jitter file popup
if ~checkfields(thisParams,'jitterFile'), return;
else
    bName = mrvFileNameExt(thisParams.jitterFile);
    v = getPopupValue(handles.popupJitter,bName);
    set(handles.popupJitter,'Value',v);
end

guidata(hObject,handles);

return;

% Gray out irrelevant text edit boxes
function grayEditText(handles,whichScan)

thisParams = handles.sParams(whichScan);
switch lower(thisParams.stimType)
    case {'stimfromscan','stimfromscan1d'}
        val1 = [.5 .5 .5]; val2 = [ 0 0 0];
    otherwise
        val1 = [ 0 0 0]; val2 = [.5 .5 .5];
end

set(handles.txtImgFile,'foregroundcolor', val2);
set(handles.txtPFile,'foregroundcolor',val2);
set(handles.txtIFilter,'foregroundcolor',val2);

set(handles.txtCycles,'foregroundcolor',val1);
set(handles.txtDirection,'foregroundcolor',val1);
set(handles.txtFrames,'foregroundcolor',val1);
set(handles.txtFrameInt,'foregroundcolor',val1);
set(handles.txtMeanLumBlk,'foregroundcolor',val1);
set(handles.txtRemoved,'foregroundcolor',val1);
set(handles.txtReps,'foregroundcolor',val1);
set(handles.txtPhase,'foregroundcolor',val1);
set(handles.txtWidth,'foregroundcolor',val1);

return;

% --- Executes on button press in cboxUD.
function cboxUD_Callback(hObject, eventdata, handles)
% hObject    handle to cboxUD (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cboxUD
return;

% --- Executes on button press in cboxCCW.
function cboxCCW_Callback(hObject, eventdata, handles)
% hObject    handle to cboxCCW (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of cboxCCW
return;

function editNumScans_Callback(hObject, eventdata, handles)
% hObject    handle to editNumScans (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editNumScans as text
%        str2double(get(hObject,'String')) returns contents of editNumScans as a double

nScans = str2double(get(hObject,'String'));
n = length(handles.sParams);
setScanSlider(hObject, nScans)

if     nScans > n, handles.sParams(n+1:nScans) = handles.sParams(n);
elseif nScans < n, handles.sParams(nScans+1:n) = [];
end

guidata(hObject,handles);

return

% --- Executes during object creation, after setting all properties.
function editNumScans_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editNumScans (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
return


%% Crystal Orientations
%
%%
%


function varargout = lvd_EditAlignedConstrainedCoordSysGUI(varargin)
% LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI MATLAB code for lvd_EditAlignedConstrainedCoordSysGUI.fig
%      LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI, by itself, creates a new LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI or raises the existing
%      singleton*.
%
%      H = LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI returns the handle to a new LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI or the handle to
%      the existing singleton*.
%
%      LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI.M with the given input arguments.
%
%      LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI('Property','Value',...) creates a new LVD_EDITALIGNEDCONSTRAINEDCOORDSYSGUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before lvd_EditAlignedConstrainedCoordSysGUI_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to lvd_EditAlignedConstrainedCoordSysGUI_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help lvd_EditAlignedConstrainedCoordSysGUI

% Last Modified by GUIDE v2.5 11-Jan-2021 15:22:06

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @lvd_EditAlignedConstrainedCoordSysGUI_OpeningFcn, ...
                   'gui_OutputFcn',  @lvd_EditAlignedConstrainedCoordSysGUI_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before lvd_EditAlignedConstrainedCoordSysGUI is made visible.
function lvd_EditAlignedConstrainedCoordSysGUI_OpeningFcn(hObject, eventdata, handles, varargin)
    % This function has no output args, see OutputFcn.
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    % varargin   command line arguments to lvd_EditAlignedConstrainedCoordSysGUI (see VARARGIN)

    % Choose default command line output for lvd_EditAlignedConstrainedCoordSysGUI
    handles.output = hObject;

    centerUIFigure(hObject);

    coordsys = varargin{1};
    setappdata(hObject, 'coordsys', coordsys);

    lvdData = varargin{2};
    setappdata(hObject, 'lvdData', lvdData);

	populateGUI(handles, lvdData, coordsys);

    % Update handles structure
    guidata(hObject, handles);

    % UIWAIT makes lvd_EditAlignedConstrainedCoordSysGUI wait for user response (see UIRESUME)
    uiwait(handles.lvd_EditAlignedConstrainedCoordSysGUI);

function populateGUI(handles, lvdData, coordsys)
    set(handles.coordSysNameText,'String',coordsys.getName());

    vectorsListBoxStr = lvdData.geometry.vectors.getListboxStr();

    handles.aVectorCombo.String = vectorsListBoxStr;
    handles.aVectorCombo.Value = lvdData.geometry.vectors.getIndsForVectors(coordsys.aVector);

    handles.cVectorCombo.String = vectorsListBoxStr;
    handles.cVectorCombo.Value = lvdData.geometry.vectors.getIndsForVectors(coordsys.cVector);

    axesListBoxStr = AlignedConstrainedCoordSysAxesEnum.getListBoxStr();

    handles.alignedVectAxisCombo.String = axesListBoxStr;
    handles.alignedVectAxisCombo.Value = AlignedConstrainedCoordSysAxesEnum.getIndForName(coordsys.aVectorAxis.name);

    handles.constrainedVectAxisCombo.String = axesListBoxStr;
    handles.constrainedVectAxisCombo.Value = AlignedConstrainedCoordSysAxesEnum.getIndForName(coordsys.cVectorAxis.name);

% --- Outputs from this function are returned to the command line.
function varargout = lvd_EditAlignedConstrainedCoordSysGUI_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
    if(isempty(handles))
        varargout{1} = false;
    else
        lvdData = getappdata(hObject, 'lvdData');
        coordsys = getappdata(hObject, 'coordsys');

        coordsys.setName(handles.coordSysNameText.String);

        coordsys.aVector = lvdData.geometry.vectors.getVectorAtInd(handles.aVectorCombo.Value);
        coordsys.cVector = lvdData.geometry.vectors.getVectorAtInd(handles.cVectorCombo.Value);

        str = handles.alignedVectAxisCombo.String{handles.alignedVectAxisCombo.Value};
        coordsys.aVectorAxis = AlignedConstrainedCoordSysAxesEnum.getEnumForListboxStr(str);

        str = handles.constrainedVectAxisCombo.String{handles.constrainedVectAxisCombo.Value};
        coordsys.cVectorAxis = AlignedConstrainedCoordSysAxesEnum.getEnumForListboxStr(str);

        varargout{1} = true;
        close(handles.lvd_EditAlignedConstrainedCoordSysGUI);
    end

% --- Executes on button press in saveAndCloseButton.
function saveAndCloseButton_Callback(hObject, eventdata, handles)
% hObject    handle to saveAndCloseButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    errMsg = validateInputs(handles);

    if(isempty(errMsg))
        uiresume(handles.lvd_EditAlignedConstrainedCoordSysGUI);
    else
        msgbox(errMsg,'Invalid Vector Inputs','error');
    end

function errMsg = validateInputs(handles)
    errMsg = {};
    lvdData = getappdata(handles.lvd_EditAlignedConstrainedCoordSysGUI, 'lvdData');

    aVector = lvdData.geometry.vectors.getVectorAtInd(handles.aVectorCombo.Value);
    cVector = lvdData.geometry.vectors.getVectorAtInd(handles.cVectorCombo.Value);
    if(aVector == cVector)
        errMsg{end+1} = 'The aligned vector and constrained vector must be different.';
    end

    str = handles.alignedVectAxisCombo.String{handles.alignedVectAxisCombo.Value};
    aVectorAxis = AlignedConstrainedCoordSysAxesEnum.getEnumForListboxStr(str);

    str = handles.constrainedVectAxisCombo.String{handles.constrainedVectAxisCombo.Value};
    cVectorAxis = AlignedConstrainedCoordSysAxesEnum.getEnumForListboxStr(str);
    if(aVectorAxis == cVectorAxis || ...
       strcmpi(aVectorAxis.baseAxis, cVectorAxis.baseAxis))
        errMsg{end+1} = 'The aligned vector axis and constrained vector axis must be different and not opposite.';
    end

    if(isempty(strtrim(handles.coordSysNameText.String)))
        errMsg{end+1} = 'Coordinate system name must contain more than white space and must not be empty.';
    end

% --- Executes on button press in cancelButton.
function cancelButton_Callback(hObject, eventdata, handles)
% hObject    handle to cancelButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
    close(handles.lvd_EditAlignedConstrainedCoordSysGUI);

function coordSysNameText_Callback(hObject, eventdata, handles)
% hObject    handle to coordSysNameText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of coordSysNameText as text
%        str2double(get(hObject,'String')) returns contents of coordSysNameText as a double

% --- Executes during object creation, after setting all properties.
function coordSysNameText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to coordSysNameText see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on key press with focus on lvd_EditAlignedConstrainedCoordSysGUI or any of its controls.
function lvd_EditAlignedConstrainedCoordSysGUI_WindowKeyPressFcn(hObject, eventdata, handles)
% hObject    handle to lvd_EditAlignedConstrainedCoordSysGUI (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.FIGURE)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)
    switch(eventdata.Key)
        case 'return'
            saveAndCloseButton_Callback(handles.saveAndCloseButton, [], handles);
        case 'enter'
            saveAndCloseButton_Callback(handles.saveAndCloseButton, [], handles);
        case 'escape'
            close(handles.lvd_EditAlignedConstrainedCoordSysGUI);
    end

% --- Executes on selection change in aVectorCombo.
function aVectorCombo_Callback(hObject, eventdata, handles)
% hObject    handle to aVectorCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns aVectorCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from aVectorCombo

% --- Executes during object creation, after setting all properties.
function aVectorCombo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to aVectorCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in cVectorCombo.
function cVectorCombo_Callback(hObject, eventdata, handles)
% hObject    handle to cVectorCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns cVectorCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from cVectorCombo

% --- Executes during object creation, after setting all properties.
function cVectorCombo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to cVectorCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in alignedVectAxisCombo.
function alignedVectAxisCombo_Callback(hObject, eventdata, handles)
% hObject    handle to alignedVectAxisCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns alignedVectAxisCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from alignedVectAxisCombo

% --- Executes during object creation, after setting all properties.
function alignedVectAxisCombo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to alignedVectAxisCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on selection change in constrainedVectAxisCombo.
function constrainedVectAxisCombo_Callback(hObject, eventdata, handles)
% hObject    handle to constrainedVectAxisCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = cellstr(get(hObject,'String')) returns constrainedVectAxisCombo contents as cell array
%        contents{get(hObject,'Value')} returns selected item from constrainedVectAxisCombo

% --- Executes during object creation, after setting all properties.
function constrainedVectAxisCombo_CreateFcn(hObject, eventdata, handles)
% hObject    handle to constrainedVectAxisCombo (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function MRSIStruct = setDimsAllZero(MRSIStruct)
    dimNames = fieldnames(MRSIStruct.dims);
    for iName = 1:length(dimNames)
        MRSIStruct = setDimension(MRSIStruct, dimNames{iName}, 0);
    end
end


function iNewDipoles = import_dipoles(iStudy, DataFile, DipolesFiles)
% IMPORT_DIPOLES: Imports a dipoles file (Neuromag xfit or CTF).
%
% USAGE:
%         iNewDipoles = import_dipoles(iStudy, DataFile, DipolesFiles) : Read files and save them in brainstorm database
%         iNewDipoles = import_dipoles(iStudy, DataFile)               : Ask files to user, read it, and save it in database
%         iNewDipoles = import_dipoles(iStudy)                         : Same wihtout attaching dipoles to any data file
%
% INPUT:
%    - iStudy       : Index of the study where to import the DipolesFiles
%    - DipolesFiles : Full filename, or cell array of filenames, of the dipoles files to import
%                     => if not specified : file to import is asked to the user

% @=============================================================================
% This function is part of the Brainstorm software:
% https://neuroimage.usc.edu/brainstorm
%
% Copyright (c) University of Southern California & McGill University
% This software is distributed under the terms of the GNU General Public License
% as published by the Free Software Foundation. Further details on the GPLv3
% license can be found at http://www.gnu.org/copyleft/gpl.html.
%
% FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
% UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
% WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
% LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
%
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel, 2010-2012

%% ===== PARSE INPUTS =====
% Argument: DipolesFiles
if (nargin < 3)
    DipolesFiles = [];
elseif ~iscell(DipolesFiles)
    DipolesFiles = {DipolesFiles};
end
% Argument: DataFile
if (nargin < 3) || isempty(DataFile)
    DataFile = '';
end

% Detect file format
FileFormat = '';
if ~isempty(DipolesFiles)
    % Get the file extenstion
    [fPath, fBase, fExt] = bst_fileparts(DipolesFiles{1});
    if ~isempty(fExt)
        fExt = lower(fExt(2:end));
        % Detect file format by extension
        switch lower(fExt)
            case 'bdip', FileFormat = 'BDIP';
            case 'mat',  FileFormat = 'BST';
            case 'dip',  FileFormat = 'CTFDIP';
            otherwise,   error('Unsupported file format.');
        end
        % Display assumed file format
        disp(['Default file format for this extension: ' FileFormat]);
        disp('If you want to specify the extension, please run this function without arguments.');
    end
end

%% ===== SELECT DIPOLES FILE =====
% If file to load was not defined : open a dialog box to select it
if isempty(DipolesFiles)
    % Get default import directory and formats
    LastUsedDirs   = bst_get('LastUsedDirs');
    DefaultFormats = bst_get('DefaultFormats');
    % Get Dipoles file
    [DipolesFiles, FileFormat] = java_getfile('open', ...
            'Import dipoles...', ...   % Window title
            LastUsedDirs.ImportData, ...    % Last used directory
            'multiple', 'files', ...        % Selection mode
            {{'.bdip'},    'Xfit binary (*.bdip)',      'BDIP'; ...
             {'_dipoles'}, 'Brainstorm (dipoles*.mat)', 'BST'; ...
             {'.dip'},     'CTF dipoles (*.dip)',       'CTFDIP' ...
            }, DefaultFormats.DipolesIn);
    % If no file was selected: exit
    if isempty(DipolesFiles)
        return
    % Make sure it's an array of files
    elseif ~iscell(DipolesFiles)
        DipolesFiles = {DipolesFiles};
    end
    % Save default import directory
    LastUsedDirs.ImportData = bst_fileparts(DipolesFiles{1});
    bst_set('LastUsedDirs', LastUsedDirs);
    % Save default import format
    DefaultFormats.DipolesIn = FileFormat;
    bst_set('DefaultFormats',  DefaultFormats);
end

%% ===== GET INFORMATION =====
% Get various information
isProgressBar = bst_progress('isVisible');
ProtocolInfo = bst_get('ProtocolInfo');
iNewDipoles = [];
% Get output study
sStudy = bst_get('Study', iStudy);
% Get channel file
ChannelFile = bst_get('ChannelFileForStudy', sStudy.FileName);

%% ===== GET COORDINATES TRANSFORMATION =====
TransfMeg = [];
% Get coordinates transformations
if ~isempty(ChannelFile)
    % Load channel file transformations
    ChannelMat = in_bst_channel(ChannelFile, 'TransfMeg');
    % If transformation Neuromag Head CS -> SCS transformation is defined
    if isfield(ChannelMat, 'TransfMeg') && ~isempty(ChannelMat.TransfMeg) && (length(ChannelMat.TransfMeg) >= 2)
        TransfMeg = ChannelMat.TransfMeg{2};
        % Add other transformations if there are some
        for i = 3:length(ChannelMat.TransfMeg)
            TransfMeg = ChannelMat.TransfMeg{i} * TransfMeg;
        end
    else
        errMsg = ['Warning: No transformation defined in this channel file.' 10 ...
                  'The dipoles locations might not be registered with the anatomy.'];
    end
else
    errMsg = ['Warning: No channel file defined for this study.' 10 10 ...
              'You should import the sensors definition before importing the dipoles, ' 10 ...
              'if not the dipoles locations might not be registered with the anatomy.'];
end
% Warning if no transformation
if isempty(TransfMeg)
    % Ask user confirmation
    isConfirm = java_dialog('confirm', [errMsg 10 10 'Import dipoles anyway ?' 10 10], 'Import dipoles');
    % If cancelled: exit
    if ~isConfirm
        return
    end
end

% Loop on each file
for iFile = 1:length(DipolesFiles)
    %% ===== LOAD DIPOLES FILE =====
    % Progress bar
    if ~isProgressBar
        bst_progress('start', 'Import dipoles', ['Loading file "' DipolesFiles{iFile} '"...']);
    end
    % Load file
    switch FileFormat
        case 'BDIP'
            DipolesMat = in_dipoles_bdip(DipolesFiles{iFile});
        case 'BST'
            DipolesMat = load(DipolesFiles{iFile});
        case 'CTFDIP'
            DipolesMat = in_dipoles_ctfdip(DipolesFiles{iFile});
        otherwise
            error('Unsupported file format.');
    end
    % Add data file
    DipolesMat.DataFile = DataFile;
    % Check that something was read
    if isempty(DipolesMat)
        error('Dipoles file could not be imported.');
    end
    % Add History field
    DipolesMat = bst_history('add', DipolesMat, 'import', ['Import from: ' DipolesFiles{iFile}]);

    %% ===== CHANGE COORDINATE SYSTEM =====
    if ~isempty(TransfMeg)
        R = TransfMeg(1:3,1:3); % Rotation
        T = TransfMeg(1:3,4);   % Translation
        % Add History field
        DipolesMat = bst_history('add', DipolesMat, 'import', sprintf('Rotation: [%1.3f,%1.3f,%1.3f; %1.3f,%1.3f,%1.3f; %1.3f,%1.3f,%1.3f]', R'));
        DipolesMat = bst_history('add', DipolesMat, 'import', sprintf('Translation: [%1.3f,%1.3f,%1.3f]', T));
        % Process each dipole
        for iDip = 1:length(DipolesMat.Dipole)
            % Position
            DipolesMat.Dipole(iDip).Loc = R * DipolesMat.Dipole(iDip).Loc + T;
            % Orientation (amplitude in each direction)
            DipolesMat.Dipole(iDip).Amplitude = R * DipolesMat.Dipole(iDip).Amplitude;
        end
    end

    %% ===== SAVE NEW FILE =====
    % Get imported base name
    [tmp__, importedBaseName, importedExt] = bst_fileparts(DipolesFiles{iFile});
    importedBaseName = strrep(importedBaseName, 'dipoles_', '');
    importedBaseName = strrep(importedBaseName, '_dipoles', '');
    importedBaseName = strrep(importedBaseName, 'dipoles', '');
    % Limit number of chars
    if (length(importedBaseName) > 15)
        importedBaseName = importedBaseName(1:15);
    end
    % Create output filename
    OutputFile = bst_fullfile(ProtocolInfo.STUDIES, bst_fileparts(sStudy.FileName), ['dipoles_', importedBaseName, '.mat']);
    OutputFile = file_unique(OutputFile);
    % Save new file in Brainstorm format
    bst_save(OutputFile, DipolesMat, 'v7');

    %% ===== UPDATE DATABASE =====
    % Create structure
    BstDipolesMat = db_template('Dipoles');
    BstDipolesMat.FileName = file_short(OutputFile);
    BstDipolesMat.Comment  = DipolesMat.Comment;
    BstDipolesMat.DataFile = DataFile;
    % Add to study
    iDipole = length(sStudy.Dipoles) + 1;
    sStudy.Dipoles(iDipole) = BstDipolesMat;
    iNewDipoles = [iNewDipoles, iDipole];
end

% Save study
bst_set('Study', iStudy, sStudy);
% Update tree
panel_protocols('UpdateNode', 'Study', iStudy);
% Save database
db_save();

% Progress bar
if ~isProgressBar
    bst_progress('stop');
end


function [] = assertEqual(a, b)
  if (a != b)
    testFailed;
  end

function [] = testFailed()
  [ST, I] = dbstack(2);
  disp(strcat("FAILED: ",  ST(1).name));


function [mri] = gui_avw_open(mri,command,parent)

% gui_avw_open - Load & Display Analyze 7.5 data
%
% Useage: [mri] = gui_avw_open(mri,[command],[parent])
%
% mri is a structure, generated by 'mri_toolbox_defaults'
% command is either 'init' or 'load'
% parent is a handle to the gui that calls this gui, useful
% for updating the UserData field of the parent from this gui.
% The mri structure may be returned to the parent when the parent
% handle is given.
%

% $Revision: 1.1 $ $Date: 2009-04-28 22:13:56 $

% Licence:  GNU GPL, no express or implied warranties
% History:  08/2002, Darren.Weber@flinders.edu.au
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if ~exist('mri','var'),
    mri = mri_toolbox_defaults;
elseif isempty(mri),
    mri = mri_toolbox_defaults;
end

if ~exist('command','var'),
    command = 'init';
elseif isempty(command),
    command = 'init';
end

command = lower(command);

switch command,
case 'init',
    if exist('parent','var'),
        MRIOpen = INIT(mri,parent);
    else
        MRIOpen = INIT(mri,'');
    end
otherwise,
    MRIOpen = get(gcbf,'Userdata');
    set(MRIOpen.gui,'Pointer','watch');
end

switch command,

case 'plot',

    MRIOpen.mri.plot = 1;
    MRIOpen.mri = mri_open(MRIOpen.mri);

case 'return',

    MRIOpen.mri.plot = 0;
    MRIOpen.mri = mri_open(MRIOpen.mri);

case 'save',

    fprintf('\ngui_avw_open: Save As not implemented yet.\n');

otherwise,

end

% -- tidy up & return

switch command,
case 'init',
case 'cancel',
    GUI.parent = MRIOpen.parent;
    mri_updateparent(GUI);
    close gcbf;
otherwise,
    set(MRIOpen.gui,'Pointer','arrow');
    set(MRIOpen.gui,'Userdata',MRIOpen);

    mri = mri_updateparent(MRIOpen,0);

    if isequal(get(MRIOpen.handles.Bhold,'Value'),0),
        close gcbf;
        if isfield(MRIOpen,'parent'),
            parent = MRIOpen.parent.gui;
        else
            parent = [];
        end
    else
        parent = MRIOpen.gui;
    end
end

return

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [MRIOpen] = INIT(mri,parent)
    % GUI General Parameters

    GUIwidth  = 500;
    GUIheight = 120;

    version = '$Revision: 1.1 $';
    name = sprintf('AVW File Open [v %s]\n',version(11:15));

    GUI = figure('Name',name,'Tag','AVW_OPEN',...
                 'NumberTitle','off',...
                 'MenuBar','none','Position',[1 1 GUIwidth GUIheight]);
    movegui(GUI,'center');

    Font.FontName   = 'Helvetica';
    Font.FontUnits  = 'Pixels';
    Font.FontSize   = 12;
    Font.FontWeight = 'normal';
    Font.FontAngle  = 'normal';

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Voltage Data Selection and Parameters

    G.Title_data = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
        'Position',[.01 .75 .17 .2],...
        'String','Data Type:','HorizontalAlignment','left');

    mri.type = 'Analyze';
    G.PmriType = uicontrol('Tag','PmriType','Parent',GUI,'Style','edit',...
        'Units','Normalized',Font,  ...
        'Position',[.20 .75 .25 .2],...
        'String',mri.type);

    switch mri.orient
        case 'auto',                mriOrient = 1;
        case 'axial unflipped',     mriOrient = 2;
        case 'coronal unflipped',   mriOrient = 3;
        case 'sagittal unflipped',  mriOrient = 4;
        case 'axial flipped',       mriOrient = 5;
        case 'coronal flipped',     mriOrient = 6;
        case 'sagittal flipped',    mriOrient = 7;
        otherwise,                  mriOrient = 1;
    end

    G.PmriOrient = uicontrol('Tag','PmriOrient','Parent',GUI,'Style','popupmenu',...
        'Units','Normalized',Font,  ...
        'Position',[.50 .75 .25 .2],...
        'TooltipString','Force loading with this orientation, otherwise use auto detection',...
        'String',{'auto' 'axial unflipped' 'coronal unflipped' 'sagittal unflipped' ...
                  'axial flipped'  'coronal flipped'  'sagittal flipped'},'Value',mriOrient,...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'MRIOpen.mri.orient = popupstr(MRIOpen.handles.PmriOrient);',...
                          'set(gcbf,''Userdata'',MRIOpen); clear MRIOpen;'));

    G.Title_path = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
        'Position',[.01 .50 .17 .2],...
        'String','Path','HorizontalAlignment','left');
    G.EmriPath = uicontrol('Parent',GUI,'Style','edit','Units','Normalized',Font,  ...
    	'Position',[.20 .50 .58 .2], 'String',mri.path,...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'MRIOpen.mri.path = get(MRIOpen.handles.EmriPath,''String'');',...
                          'set(gcbf,''Userdata'',MRIOpen); clear MRIOpen;'));

    G.Title_file = uicontrol('Parent',GUI,'Style','text','Units','Normalized',Font, ...
        'Position',[.01 .25 .17 .2],...
        'String','File','HorizontalAlignment','left');
    G.EmriFile = uicontrol('Parent',GUI,'Style','edit','Units','Normalized',Font,  ...
    	'Position',[.20 .25 .58 .2], 'String',mri.file,...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'MRIOpen.mri.file = get(MRIOpen.handles.EmriFile,''String'');',...
                          'set(gcbf,''Userdata'',MRIOpen); clear MRIOpen;'));

    Font.FontWeight = 'bold';

    % BROWSE: Look for the data
    browsecommand = strcat('MRIOpen = get(gcbf,''Userdata'');',...
        'cd(MRIOpen.mri.path);',...
        '[file, path] = uigetfile(',...
        '{''*.hdr;*.img'', ''Analyze Files (*.hdr,*.img)'';', ...
        ' ''*.*'',   ''All Files (*.*)''},', ...
        '''Select MRI File'');',...
        'if ~isequal(path,0), MRIOpen.mri.path = path; end;',...
        'if ~isequal(file,0), MRIOpen.mri.file = file; end;',...
        'set(MRIOpen.handles.EmriPath,''String'',MRIOpen.mri.path);',...
        'set(MRIOpen.handles.EmriFile,''String'',MRIOpen.mri.file);',...
        'if ~isempty(findstr(file,''.hdr'')) | ~isempty(findstr(file,''.img'')), ',...
            'set(MRIOpen.handles.PmriType,''Value'',1); ',...
            'MRIOpen.mri.type = popupstr(MRIOpen.handles.PmriType);',...
        'else, ',...
            'set(MRIOpen.handles.PmriType,''Value'',3); ',...
            'MRIOpen.mri.type = popupstr(MRIOpen.handles.PmriType);',...
        'end;',...
        'set(gcbf,''Userdata'',MRIOpen); clear MRIOpen file path;');
    G.BmriFile = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized',Font, ...
        'Position',[.01 .01 .17 .2], 'String','BROWSE',...
        'BackgroundColor',[0.8 0.8 0.0],...
        'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
        'Callback', browsecommand );

    % PLOT: Load & plot the data!
    G.Bplot = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
        'Position',[.20 .01 .18 .2],...
        'String','PLOT','BusyAction','queue',...
        'TooltipString','Plot the MRI data and return p struct.',...
        'BackgroundColor',[0.0 0.5 0.0],...
        'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'mri = gui_avw_open(MRIOpen.mri,''plot'');',...
                          'clear MRIOpen;'));

    % Save As
	G.Bsave = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
        'Position',[.40 .01 .18 .2],'HorizontalAlignment', 'center',...
        'String','SAVE AS','TooltipString','MRI File Conversion Tool (not implemented yet)',...
        'BusyAction','queue',...
        'Visible','on',...
        'BackgroundColor',[0.0 0.0 0.75],...
        'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'mri = gui_avw_open(MRIOpen.mri,''save'');',...
                          'clear MRIOpen;'));

    % Quit, return file parameters
    G.Breturn = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
        'Position',[.60 .01 .18 .2],...
        'String','RETURN','BusyAction','queue',...
        'TooltipString','Return p struct to workspace and parent GUI.',...
        'BackgroundColor',[0.75 0.0 0.0],...
        'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'mri = gui_avw_open(MRIOpen.mri,''return'');',...
                          'clear MRIOpen;'));

    % Cancel
    G.Bcancel = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
        'Position',[.80 .01 .18 .2],...
        'String','CANCEL','BusyAction','queue',...
        'TooltipString','Close, do not return parameters.',...
        'BackgroundColor',[0.75 0.0 0.0],...
        'ForegroundColor', [1 1 1], 'HorizontalAlignment', 'center',...
        'Callback',strcat('MRIOpen = get(gcbf,''Userdata'');',...
                          'mri = gui_avw_open(MRIOpen.mri,''cancel'');',...
                          'clear MRIOpen;'));

	% Help
	G.Bhelp = uicontrol('Parent',GUI,'Style','pushbutton','Units','Normalized', Font, ...
        'Position',[.80 .25 .18 .2],'String','Help','BusyAction','queue',...
        'BackgroundColor',[1 1 0],...
        'ForegroundColor',[0 0 0], 'HorizontalAlignment', 'center',...
        'Callback','doc mri_toolbox;');

    % Hold GUI Open checkbox
	G.Bhold = uicontrol('Parent',GUI,'Style','checkbox','Units','Normalized', Font, ...
        'Position',[.80 .50 .18 .2],'String','Hold GUI','BusyAction','queue',...
        'TooltipString','MRI File Load GUI remains open after ''Plot'' or ''Return'' commands.',...
        'Value',mri.hold,'HorizontalAlignment', 'center');

    % Store userdata
    if exist('parent','var'), MRIOpen.parent.gui = parent; end
    MRIOpen.gui = GUI;
    MRIOpen.handles = G;
    MRIOpen.mri = mri;
    set(GUI,'Userdata',MRIOpen);
    set(GUI,'HandleVisibility','callback');

return