Authors: Francois Tadel, Elizabeth Bock, Matthias Sure, Sylvain Baillet
The previous tutorials explained how to use Brainstorm in an interactive way to process one subject with two acquisition runs. In the context of a typical neuroimaging study, you may have tens or hundreds of subjects to process in the same way, it is unrealistic to do everything manually. Some parts of the analysis can be processed in batches with no direct supervision, others require more attention. This tutorial introduces tools and tricks that will help you assemble an efficient analysis pipeline.
The easiest way to get started with a new Brainstorm script is to use the script generator, already introduced in the tutorial Select files and run processes. Select some files in the Process1 or Process2 tabs, select a list of processes, and use the menu Generate .m script. The example below should work with the protocol "TutorialIntroduction" created during the introduction tutorials.
In the Process1 tab, leave the selection box empty and click on [Run]. Instead of selecting the files from the Brainstorm interface, we will select them directly from the database using a script.
Select process File > Select files: Recordings (do not execute immediately)
Subject=Subject01, Condition=[Empty], File name=Avg: deviant (the space is important).
This process selects all the recordings with a comment including the string "Avg: deviant", from all the folders in Subject01 (except for "Intra-subject" and "Common files"). We expect to get two files: the averages of the deviant condition for both runs.
Add process Pre-process > Band-pass filter: Lower cutoff=0Hz, Upper cutoff=30Hz, 60dB. Add process File > Save snapshot: Recordings time series, Sensors=MEG.
This will apply a low-pass filter at 30Hz and save a screen capture of the signals in the report.
Do not run the pipeline, select the menu Generate .m script instead. It saves a new .m file and opens it in the Matlab editor. Close the pipeline editor window and look at the script.
The script you just generated can be the starting point to your own custom script. The following sections explain line by line how they work and how to edit them.
Line by line: Header
% Script generated by Brainstorm (19-Jul-2016)
All the lines starting with a "%" are comments, they are never executed.
sFiles: The list of files in input. Currently empty because we did not select anything in the Process1 list. If we had selected files, it would contain a cell array of strings with relative file paths.
SubjectNames: List of subject names that are used in the script. Most of the times, the generated scripts contain only one entry, but it is written as a cell array to make it easier to extend to multiple subjects with a loop (described further in this tutorial).
% Start a new report
bst_report('Start', sFiles);
Starts a new report of activity: Clears all the previous logs and gets ready to record new messages. The report will collect all the messages that are generated during the execution of the script by the various processes. You can explicitly add screen captures and additional messages to the current report with the function bst_report. This report will remain open until the function bst_report('Start') is called again. To display the current report, use the menu File > Report viewer.
The syntax function_name('SubFunction', arguments) is used a lot in Brainstorm: it calls a subfunction available inside a .m file. This line above calls the function Start() in the file brainstorm3/toolbox/process/bst_report.m. This is made possible with the use of the short script "macro_method". Many of the Brainstorm .m files are actually libraries of functions, rather than simple "scripts" or "functions".
You will find one block per process you selected in the pipeline editor. They all have the same syntax:
output_files = bst_process('CallProcess', process_name, input_files_A, input_files_B, options_list);
process_name: String indicating the function corresponding to the process to execute. To know from the pipeline editor what is the path to the process function: hover your mouse over the selected process, as illustrated in this tutorial.
input_files_A: List of input files in Process1, or FilesA in Process2. It can be a cell array of file names (full path, or relative path from the protocol folder), or an array of structures describing the files in the database (returned by a previous call to bst_process).
input_files_B: Empty for Process1, or FilesB in Process2. Cell array of strings, or array of struct.
options_list: Pairs of (option_name, option_values), one pair for each option of the process.
output_files: Array of structures describing the files in output of the process. If the process created new files, this variable points at them. If the process didn't create new files or was modifying exiting files, this variable points at the input files.
Line by line: Footer
% Save and display report
ReportFile = bst_report('Save', sFiles);
Closes the current report and saves it in the user report folder ($HOME/.brainstorm/reports). These reports are in .mat format and contain all the information necessary to re-run the execution exactly in the same way, but they are not easy to read.
The parameter "sFiles" is optional, it indicates what are the files that are considered as the final results of the script. You can remove it without breaking your script: ReportFile = bst_report('Save');
bst_report('Open', ReportFile);
Opens the report viewer to display what happened during the execution. This is equivalent to using the menu File > Report viewer. You can comment this line (ie. add a "%" at the beginning of the line) if you don't want to show the report at the end of the execution.
% bst_report('Export', ReportFile, ExportDir);
This function exports the report in readable format, as an HTML file that includes all the screen captures embedded in it. It is disabled by default. If you want to use this feature: remove the "%" at the beginning of the line, and define the variable ExportDir.
ExportDir must be a string that defines where to save the HTML report. It can be either the absolute path to a HTML file (eg. 'C:\Users\myuser\Documents\report_example.html') or just a folder (eg. 'C:\Users\myuser\Documents'). If you enter only a path to a folder, a default file name including the protocol name and a date tag is generated (report_ProtocolName_YYMMDD_HHMMSS.html).
Simplify the calls
The script you generated is like any Matlab script: you can edit it, rename the variables, add tests and loops, etc. The first important thing to understand is how to edit the options and change the inputs/outputs. The script generator uses only one variable for all the file lists (sFiles) and the output process is always the input of the following process. This is usually too restrictive to write a full analysis script: we commonly need to have multiple lists of files or to run two different operations on the same file.
Let's consider the first process call, which selects the averages for the Deviant condition in both runs.
There is no need to set the parameter sFiles, because there is no input, you can replace it with an empty matrix []. You can therefore remove the line "sFiles = [];". We can also rename the output variable "sAvgData", to be more specific.
Edit the call to the low-pass filter: Change the input to sAvgData and the output to sAvgDataLow, this way you will be able to keep track of the two files if you need to use them independently later.
Edit the call to the snapshot process: Change the input to sAvgDataLow, and remove the output parameter (we are not expecting any output file from it).
bst_process('CallProcess', 'process_snapshot', sAvgDataLow, [], ...
'target', 5, ... % Recordings time series
'modality', 1); % MEG (All)
Replace the last lines with the following code, in order to export the report instead of opening in the report viewer (edit the file path to point at your own user folder instead).
Select the code for the first process in the Matlab editor, right-click > Evaluate selection (or press F9).
If you haven't executed your script yet, you will get the following error in the Matlab command window:
Undefined variable "SubjectNames" or class "SubjectNames".
The variable SubjectNames is not defined yet: Execute the first lines "SubjectNames = {'Subject01'}", then try again. You should now have a new variable in your Matlab workspace, which points at the two average files. Type "sAvgData(1)" in your command window to display the first element:
The field "sAvgData(1).FileName" contains the relative path to the to the Deviant average in the first run. This structure sAvgData contains also a lot of information that can be helpful in your script:
iStudy / iItem: Reference of the file in the database (described later in this tutorial).
FileType: 'raw' (continuous files), 'data' (recordings), 'results' (sources), 'timefreq' (time-frequency, spectrum and connectivity), or 'matrix' (any time series extracted from other files).
Comment: Comment/Name field of the file (what is displayed in the database explorer).
Condition: Name of the condition/folder in which the file is located.
SubjectFile: Relative path to the subject file (brainstormsubject.mat).
SubjectName: Name of the subject (must be the same as the folder name).
DataFile: For types 'results' or 'timefreq', path of the parent file in the database explorer.
ChannelFile: Relative path to the channel file.
ChannelTypes: Cell array of channel types available for the input file.
Naming conventions
To help you navigate in the Brainstorm code, here are some naming conventions:
Structures: Name starting with a "s" followed by a capital letter (eg. sFiles, sStudy, sSubject).
Indices: Either loop variables or array indices, name starting with a "i" (eg. iSubject, iStudy, iTime).
Counts: Number of elements in a group, name starting with a "n" (eg. nAvg, nTrials, nSubjects).
Graphic handles: Matlab graphic objects, name starting with a "h" (eg. hFig, hAxes, hLine, hText).
File names: Scripts and functions, only lower case, separation with "_" (eg. process_fft, bst_get).
Sub-functions: Inside a .m file, name starting with a capital, CamelCase (eg. CallProcess, Start).
Running the script
The simplified script looks like this:
% Input files
SubjectNames = {'Subject01'};
% Start a new report
bst_report('Start');
% Process: Select data files in: Subject01/*/Avg: deviant
sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
'subjectname', SubjectNames{1}, ...
'tag', 'Avg: deviant');
% Process: Low-pass:30Hz
sAvgDataLow = bst_process('CallProcess', 'process_bandpass', sAvgData, [], ...
'sensortypes', 'MEG', ...
'highpass', 0, ...
'lowpass', 30, ...
'attenuation', 'strict'); % 60dB
% Process: Snapshot: Recordings time series
bst_process('CallProcess', 'process_snapshot', sAvgDataLow, [], ...
'target', 5, ... % Recordings time series
'modality', 1); % MEG (All)
% Save and display report
ReportFile = bst_report('Save');
bst_report('Export', ReportFile, 'C:\Users\franc\Documents\report_test.html');
You have three ways to execute it:
Select all the lines (Ctrl+A) and evaluate it in Matlab (F9).
In the Editor toolbar of the Matlab environment, click on the button [Run].
Save the file, go to this folder with Matlab (or add it to your path) and type the name of the script in the command window (without the ".m" at the end).
At the end of the execution, nothing happens, because we indicated we wanted to export the report instead of opening it. To check out the report of execution: use the menu File > Report viewer from the Brainstorm window, or open the file report_test.html that was saved somewhere on your computer.
In this page, you can review everything that happened in the script: when it was executed, how long it took, what are the processes that were executed, some additional messages (two files were selected with the first process) and the screen captures taken by process_snapshot.
Running the script again
If you execute the script again, it will not behave as expected anymore. The selection process we used assumes that there is only one file per folder with a name that includes "Avg: deviant". This is not the case anymore after the execution, because the low-pass filtered files also contain the same string. The execution of the first process of the script now returns 4 files.
In order to exclude the low-pass filtered files from this selection, you can add another process that will refine the selection. Use the script generator again to create a template call for another process, then copy-paste it in your script.
In Process1: Select any recordings file (we will not run anything, just generate a script).
Select process File > Select files: By tag: Search="low", Search the file name, Ignore the files.
Select the menu Generate .m script (make sure you do not overwrite the script you are currently working on), then close the pipeline editor.
Copy-paste and edit the call to process_select_tag to your main script.
Now the file selection part of your script should look like this, and should return only two files:
% Process: Select data files in: Subject01/*/Avg: Deviant
sAvgData = bst_process('CallProcess', 'process_select_files_data', [], [], ...
'subjectname', SubjectNames{1}, ...
'tag', 'Avg: deviant');
% Process: Ignore file names with tag: low
sAvgData = bst_process('CallProcess', 'process_select_tag', sAvgData, [], ...
'tag', 'low', ...
'search', 2, ... % Search the file names
'select', 2); % Ignore the files with the tag
With this last modification, your script is more robust. It can be executed multiple times without completely changing its behavior. When you are fetching files from the database using tags or file names, always pay attention to this aspect: the database grows and the further you go, the more specific your requests have to be.
A good practice can be to tag explicitly the output files your script generates if you need to fetch them later. You can use the process File > Add tag and File > Set name.
Starting Brainstorm
Brainstorm must be running in the background for these scripts to run properly. The interface doesn't have to be visible on the screen, but the database engine must be running for processing requests. At the beginning of your script, you can explicitly start or restart Brainstorm.
brainstorm: Start Brainstorm with the regular GUI.
brainstorm nogui: Start in silent mode. The Java GUI is created but hidden, the progress bar is not shown, all the processes run without user interactions, using default options instead of asking interactively. Visualization figures opened in the processing scripts are still created and made visible.
brainstorm server: Start in headless mode, for execution on a distant computation server that does not have any graphical capability or display attached to it. In this mode, none of the Java GUI elements are created, and the Matlab figures are not displayed. Whether you would be able to add screen captures to your execution reports depends mostly on the Matlab version available of your server (see section below Running scripts on a cluster).
brainstorm <script.m> <parameters>: Start Brainstorm in server mode, execute a script and quit Brainstorm. This allows executing any Matlab or Brainstorm script from the command line. This works also from the compiled version of Brainstorm, executed with the free MATLAB Runtime (see installation instructions, section "without Matlab"). Add the full path to the script and parameters to the command line:
brainstorm ... local: Instead of using a user defined brainstorm_db folder, it would use the default folder for the database: $HOME/.brainstorm/local_db
If you want to start Brainstorm only if it is not already running, you can use the following code:
if ~brainstorm('status')
brainstorm nogui
end
To select a specific protocol at the beginning of your script:
ProtocolName = 'TutorialIntroduction';
% Get the protocol index
iProtocol = bst_get('Protocol', ProtocolName);
if isempty(iProtocol)
error(['Unknown protocol: ' ProtocolName]);
end
% Select the current procotol
gui_brainstorm('SetCurrentProtocol', iProtocol);
brainstorm stop % Quit Brainstorm
brainstorm update % Download and install latest Brainstorm update (see bst_update)
brainstorm reset % Re-initialize Brainstorm database and preferences
brainstorm digitize % Digitize electrodes positions and head shape using a Polhemus
brainstorm setpath % Add Brainstorm subdirectories to current path
brainstorm info % Open Brainstorm website
brainstorm forum % Open Brainstorm forum
brainstorm license % Display license
Database requests
The functions bst_get and bst_set allow you to query the database, access the configuration of the software and modify some display parameters. The complete reference documentation of these functions is included directly in their code (brainstorm3/toolbox/core/bst_get.m and bst_set.m).
Let's start with a few simple examples:
>> ProtocolInfo = bst_get('ProtocolInfo') % Configuration of the current protocol
ProtocolInfo =
Comment: 'TutorialIntroduction'
STUDIES: 'C:\Work\Protocols\TutorialIntroduction\data'
SUBJECTS: 'C:\Work\Protocols\TutorialIntroduction\anat'
iStudy: 6
UseDefaultAnat: 0
UseDefaultChannel: 0
>> isGUI = bst_get('isGUI') % Is the Brainstorm interface displayed (0=no, 1=yes)
>> bst_set('FlipYAxis', 1) % New figures will have the Y axis flipped
>> bst_set('TSDisplayMode', 'butterfly') % New figures will use a "butterfly" view
To reference the files in the database, each protocol is subdivided in Subjects (the "anat" folder, containing the MRI, surfaces and atlases) and Studies (the "data" folder, including the recordings, channel files and all the analyses). Each Study corresponds to a sub-folder (eg. protocol/data/subject01/run01/), and is attached to only one subject.
Subjects and Studies are referenced in the protocol with a unique index, most of the time kept in variables named iSubject and iStudy. The files available in them are also referenced with indices, with variables such as iAnatomy, iSurface, iData, iHeadModel, iResults or iTimefreq. You can see the indices in the database explorer by hovering your mouse over the nodes files and folders:
Example: Getting the study structure from the variable sAvgData, defined in the script:
>> sAvgData(1)
ans =
iStudy: 6
iItem: 1
...
>> sStudy = bst_get('Study', sAvgData(1).iStudy) % Get study struct with its index
sStudy =
Name: 'S01_AEF_20131218_01_600Hz_notch'
FileName: 'Subject01/S01_AEF_20131218_01_600Hz_notch/brainstormstudy.mat'
DateOfStudy: '13-May-2016'
BrainStormSubject: 'Subject01/brainstormsubject.mat' % Subject filename
Condition: {'S01_AEF_20131218_01_600Hz_notch'} % Name of the folder
Channel: [1x1 struct] % Channel file
iChannel: [] % Not used anymore
Data: [1x242 struct] % List of "data" files in the folder
HeadModel: [1x1 struct] % List of head models in the folder
iHeadModel: 1 % Default head model (file in green)
Result: [1x244 struct] % List of source files and links
Stat: [1x0 struct] % List of statistical results
Image: [0x0 struct] % List of images
NoiseCov: [1x2 struct] % Noise(1) and data(2) covariance files
Dipoles: [0x0 struct] % List of dipole files in the folder
Timefreq: [1x247 struct] % List of time-frequency files
Matrix: [0x0 struct] % List of "matrix" files in the folder
Example: Getting the data structure.
% Get the structure representing the file from sStudy
>> sData = sStudy.Data(sAvgData(1).iItem)
sData =
FileName: '..._01_600Hz_notch/data_deviant_average_160513_1329.mat'
Comment: 'Avg: deviant (39 files)' % File name
DataType: 'recordings' % Type of data in the file
BadTrial: 0 % If 1, the trial is marked as bad
Example: Getting the subject structure.
% Get subject structure from filename (lists the files in the subject folder)
>> sSubject = bst_get('Subject', sStudy.BrainStormSubject)
sSubject =
Name: 'Subject01' % Subject name, same as folder name
Comments: '' % Not used much
FileName: 'Subject01/brainstormsubject.mat'
DateOfAcquisition: '' % Not used anymore
Anatomy: [1x1 struct] % List of MRI volumes
Surface: [1x9 struct] % List of surfaces
iAnatomy: 1 % Index of default MRI
iScalp: 9 % Index of default head surface
iCortex: 4 % Index of default cortex surface
iInnerSkull: [] % Index of default inner skull surface
iOuterSkull: [] % Index of default outer skull surface
iOther: [] % Not used anymore
UseDefaultAnat: 0 % If 1: Use the default anatomy
UseDefaultChannel: 0 % 0=one/folder, 1=one/subject, 2=one global
Example: Getting the study structure and data index from a file name.
Many other options are available for searching files in the database with bst_get. We cannot list them all in this page, but you can refer to the code of bst_get.m for more information.
1 function [argout1, argout2, argout3, argout4, argout5] = bst_get( varargin )
2 % BST_GET: Get a Brainstorm structure.
3 % This function is used to abstract the way that these structures are stored.
4 %
5 % USAGE :
6 % ====== DIRECTORIES ==================================================================
7 % - bst_get('UserDir') : User home directory
8 % - bst_get('BrainstormHomeDir') : Application directory of brainstorm
9 % - bst_get('BrainstormUserDir') : User home directory for brainstorm (<home>/.brainstorm/)
10 % - bst_get('BrainstormTmpDir') : User brainstorm temporary directory (Default: <home>/.brainstorm/tmp/)
11 % - bst_get('BrainstormTmpDir', isForcedDefault) : User DEFAULT brainstorm temporary directory (<home>/.brainstorm/tmp/)
12 % - bst_get('BrainstormDocDir') : Doc folder folder of the Brainstorm distribution (may vary in compiled versions)
13 % - bst_get('BrainstormDefaultsDir') : Defaults folder folder of the Brainstorm distribution (may vary in compiled versions)
14 % - bst_get('BrainstormPluginDir') : User home directory for brainstorm (<home>/.brainstorm/)
15 % - bst_get('UserReportsDir') : User reports directory (<home>/.brainstorm/reports/)
16 % - bst_get('UserMexDir') : User temporary directory (<home>/.brainstorm/mex/)
17 % - bst_get('UserProcessDir') : User custom processes directory (<home>/.brainstorm/process/)
18 % - bst_get('UserDefaultsDir') : User defaults directory (<home>/.brainstorm/defaults/)
19 % - bst_get('UserPluginsDir') : User plugins directory (<home>/.brainstorm/plugins/)
20 % - bst_get('BrainstormDbFile') : User brainstorm.mat file (<home>/.brainstorm/brainstorm.mat)
21 % - bst_get('BrainstormDbDir') : User database directory (contains all the brainstorm protocols)
22 % - bst_get('DirDefaultSubject') : Directory name of the default subject
23 % - bst_get('DirDefaultStudy') : Directory name of the default study for each subject
24 % - bst_get('DirAnalysisInter') : Directory name of the inter-subject analysis study
25 % - bst_get('DirAnalysisIntra') : Directory name of the intra-subject analysis study (for each subject)
26 % - bst_get('AnatomyDefaults') : Get the contents of directory bstDir/defaults/anatomy
27 % - bst_get('MniAtlasDefaults') : Get the contents of directory bstDir/defaults/mniatlas
28 % - bst_get('EegDefaults') : Get the contents of directory bstDir/defaults/eeg
29 % - bst_get('LastUsedDirs') : Structure with all the last used directories (last used)
30 % - bst_get('OsType', isMatlab=1) : Get a string that describes the operating system (if isMatlab=1 return the Matlab/JVM platform, else return the real host system)
31 % - bst_get('FileFilters', DataType) : Get the list of import filters for a specific data type
32 % - bst_get('PluginCustomPath') : Full custom path to all plugins
33 % - bst_get('BrainSuiteDir') : Full path to a local installation of BrainSuite
34 % - bst_get('SpmTpmAtlas') : Full path to the SPM atlas TPM.nii
35 % - bst_get('PythonExe') : Path to the python executable
36 %
37 % ====== PROTOCOLS ====================================================================
38 % - bst_get('iProtocol') : Indice of current protocol
39 % - bst_get('Protocol', ProtocolName): Return the indice of the protocol ProtocolName, or [] if it doesn't exist
40 % - bst_get('ProtocolInfo') : Definition structure for current protocol
41 % - bst_get('ProtocolSubjects') : Subjects list for current protocol
42 % - bst_get('ProtocolStudies') : Studies list for current protocol
43 % - bst_get('isProtocolLoaded') : 1 if the protocol has been loaded, 0 else
44 % - bst_get('isProtocolModified') : 1 if the protocol has been modified, 0 else
45 %
46 % ====== STUDIES ======================================================================
47 % - bst_get('Study', StudyFileName) : Get one study in current protocol with its file name
48 % - bst_get('Study', iStudies) : Get one or more studies
49 % - bst_get('Study') : Get current study in current protocol
50 % - bst_get('StudyCount') : Get number of studies in the current protocol
51 % - bst_get('StudyWithSubject', SubjectFile) : Find studies associated with a given subject file (WITHOUT the system studies ('intra_subject', 'default_study'))
52 % - bst_get('StudyWithSubject', ..., 'intra_subject') : Find studies ... INCLUDING 'intra_subject' study
53 % - bst_get('StudyWithSubject', ..., 'default_study') : Find studies ... INCLUDING 'default_study' study
54 % - bst_get('StudyWithCondition', ConditionPath) : Find studies for a given condition path
55 % - bst_get('ChannelStudiesWithSubject', iSubjects) : Get all the studies where there should be a channel file for a list of subjects
56 % - bst_get('AnalysisIntraStudy', iSubject) : Get the default analysis study for target subject
57 % - bst_get('AnalysisInterStudy') : Get the default analysis study for inter-subject analysis
58 % - bst_get('DefaultStudy', iSubject) : Get the default study for target subject (by subject indice)
59 % - bst_get('DefaultStudy') : Get the global default study (common to all subjects)
60 % - bst_get('DefaultStudy', SubjectFile) : Get the default study for target subject (by filename)
61 % - bst_get('ChannelFile', ChannelFile) : Find a channel file in current protocol
62 % - bst_get('ChannelFileForStudy', StudyFile/DataFile) : Find a channel file in current protocol
63 % - bst_get('ChannelForStudy', iStudies) : Return current Channel struct for target study
64 % - bst_get('ChannelModalities', ChannelFile) : Return displayable modalities for a Channel file
65 % - bst_get('ChannelModalities', DataFile) : Return displayable modalities for a Data/Results/Timefreq... file
66 % - bst_get('ChannelDevice', ChannelFile) : Return acquisistion device for a channel file
67 % - bst_get('TimefreqDisplayModalities', TfFile) : Get displayable modalities for a TF file based on recordings
68 % - bst_get('HeadModelForStudy', iStudy) : Return current HeadModel struct for target study
69 % - bst_get('HeadModelFile', HeadModelFile) : Find a HeadModel file in current protocol
70 % - bst_get('HeadModelFile', HeadModelFile, iStudies): Find a HeadModel file in current protocol
71 % - bst_get('NoiseCovFile', NoiseCovFile) : Find a noise covariance file file in current protocol
72 % - bst_get('NoiseCovFile', NoiseCovFile, iStudies) : Find a noise covariance file in current protocol
73 % - bst_get('NoiseCovFile', DataCovFile) : Find a data covariance file file in current protocol
74 % - bst_get('NoiseCovFile', DataCovFile, iStudies) : Find a data covariance file file in current protocol
75 % - bst_get('DataFile', DataFile) : Find a DataFile in current protocol
76 % - bst_get('DataFile', DataFile, iStudies) : Find a DataFile in current protocol
77 % - bst_get('DataForDataList', iStudy, DataListName) : Find all the DataFiles grouped by a data list
78 % - bst_get('DataForStudy', iStudy) : Find all the Data files that are dependent on the channel/headmodel of a given study
79 % - bst_get('DataForStudies', iStudies)
80 % - bst_get('DataForChannelFile', ChannelFile) : Find all the DataFiles that use the given ChannelFile
81 % - bst_get('ResultsFile', ResultsFile) : Find a ResultsFile in current protocol
82 % - bst_get('ResultsFile', ResultsFile, iStudies) : Find a ResultsFile in input studies
83 % - bst_get('ResultsForDataFile', DataFile, iStudies): Find all results computed based on DataFile
84 % - bst_get('StatFile', StatFile) : Find a StatFile in current protocol
85 % - bst_get('StatFile', StatFile, iStudies) : Find a StatFile in input studies
86 % - bst_get('StatForDataFile', DataFile, iStudies)
87 % - bst_get('StatForDataFile', DataFile)
88 % - bst_get('TimefreqFile', TimefreqFile)
89 % - bst_get('TimefreqFile', TimefreqFile, iStudies)
90 % - bst_get('TimefreqForFile', FileName, iStudies) : Find all timefreq files computed based on target file
91 % - bst_get('TimefreqForKernel', KernelFile)
92 % - bst_get('DipolesFile', DipolesFile)
93 % - bst_get('DipolesFile', DipolesFile, iStudies)
94 % - bst_get('DipolesForFile', FileName, iStudies) : Find all dipoles files computed based on target file
95 % - bst_get('DipolesForKernel', KernelFile)
96 % - bst_get('MatrixFile', MatrixFile)
97 % - bst_get('MatrixFile', MatrixFile, iStudies)
98 % - bst_get('MatrixForMatrixList', iStudy, MatrixListName)
99 % - bst_get('AnyFile', AnyFile)
100 % - bst_get('AnyFile', AnyFile, iStudies)
101 % - bst_get('RelatedDataFile', FileName)
102 % - bst_get('RelatedDataFile', FileName, iStudies)
103 % - bst_get('GetFilenames')
104 %
105 % ====== SUBJECTS ======================================================================
106 % - bst_get('Subject', SubjectFileName, isRaw) : Find a subject in current protocol with its file name
107 % - bst_get('Subject', SubjectName, isRaw) : Find a subject in current protocol with its name
108 % - bst_get('Subject', iSubject) : Get a subject (normal or default if iSubject==0)
109 % - bst_get('Subject') : Get current subject in current protocol
110 % - bst_get('SubjectCount') : Get number of studies in the current protocol
111 % - bst_get('NormalizedSubjectName') : Name of the subject with a normalized anatomy
112 % - bst_get('NormalizedSubject') : Get groupd analysis subject for the current protocol
113 % - bst_get('ConditionsForSubject', SubjectFile) : Find all conditions for a given subject
114 % - bst_get('SurfaceFile', SurfaceFile) : Find a surface in current protocol
115 % - bst_get('SurfaceFileByType', iSubject, SurfaceType) : Find surfaces with given type for subject #i (default only)
116 % - bst_get('SurfaceFileByType', SubjectFile, SurfaceType) : Find surfaces with given type for subject SubjectFile (default only)
117 % - bst_get('SurfaceFileByType', SurfaceName, SurfaceType) : Find surfaces with given type for subject that also has surface SurfaceName (default only)
118 % - bst_get('SurfaceFileByType', MriName, SurfaceType) : Find surfaces with given type for subject that also has MRI MriName (default only)
119 % - bst_get('SurfaceFileByType', ..., ..., isDefaultOnly) : If 0, return all the surfaces of the given type, instead of only the default surface
120 % - bst_get('MriFile', MriFile) : Find a MRI in current protocol
121 %
122 % ====== GUI =================================================================
123 % - bst_get('BstControls') : Return main Brainstorm GUI structure
124 % - bst_get('BstFrame') : Return main Brainstorm JFrame
125 % - bst_get('isGUI') : Return 1 if the Brainstorm interface is displayed
126 % - bst_get('GuiLevel') : Return GUI level: -1=server, 0=nogui, 1=normal, 2=autopilot
127 % - bst_get('ScreenDef') : Get screens configuration
128 % - bst_get('DecorationSize') : Get dimensions of the windows decorations
129 % - bst_get('Layout') : Configuration of the main Brainstorm window
130 % - bst_get('Layout', prop) : Get one property in the layout properties
131 % - bst_get('PanelContainer') : Display list of registered panel containers
132 % - bst_get('PanelContainer', ContainerName) : Get a panel container handle
133 % - bst_get('Panel') : Display list of registered panels
134 % - bst_get('Panel', PanelName) : Find a panel with its name
135 % - bst_get('PanelControls', PanelName) : Get the controls of a panel
136 % - bst_get('Clipboard') : Nodes that were copied from the interface
137 % - bst_get('FigFont') : Standard font size displayed in the figures
138 % - bst_get('Font') : Create a Java font, scaled for the operating system
139 %
140 % ====== CONFIGURATION =================================================================
141 % - bst_get('Version') : Brainstorm version
142 % - bst_get('MatlabVersion') : Matlab version (version number * 100, eg. 801)
143 % - bst_get('MatlabReleaseName') : Matlab version (release name, eg. "R2014a")
144 % - bst_get('JavaVersion') : Java version
145 % - bst_get('isJavacomponent') : Returns 1 if javacomponent is available (Matlab < 2019b), 0 otherwise
146 % - bst_get('SystemMemory') : Amount of memory available, in Mb
147 % - bst_get('ByteOrder') : {'l','b'} - Byte order used to read and save binary files
148 % - bst_get('TSDisplayMode') : {'butterfly','column'}
149 % - bst_get('ElectrodeConfig', Modality) : Structure describing the current display values for SEEG/ECOG/EEG contacts
150 % - bst_get('AutoUpdates') : {0,1} - If 1, check automatically for updates at startup
151 % - bst_get('ForceMatCompression') : {0,1} - If 1, always save mat-files using the v7 format instead of v6
152 % - bst_get('IgnoreMemoryWarnings') : {0,1} - If 1, do not display memory warnings at the Brainstorm startup
153 % - bst_get('ExpertMode') : {0,1} - If 1, show advanced options that regular user do not see
154 % - bst_get('DisplayGFP') : {0,1} - If 1, the GFP is displayed on all the time series figures
155 % - bst_get('DownsampleTimeSeries') : {0,1,...} - If > 0, downsample dense time series for faster display
156 % - bst_get('DisableOpenGL') : {0,1,2} - If 1, do not use OpenGL renderer; if 2, use software OpenGL
157 % - bst_get('InterfaceScaling') : {100,125,150,...} - Scales the Brainstorm GUI by a fixed factor
158 % - bst_get('GraphicsSmoothing') : {0,1} - If 1, uses the graphics smoothing (Matlab >= 2014b)
159 % - bst_get('SystemCopy') : {0,1} - If 1, uses the system calls mv/cp instead of movefile/copyfile (Linux only)
160 % - bst_get('JOGLVersion') : {0,1,2}, Detect the current version of JOGL available in Matlab
161 % - bst_get('DefaultFormats') : Default formats for importing/exporting data, channels, ... (last used)
162 % - bst_get('BFSProperties') : Conductivities and thicknesses for 3-shell spherical forward model
163 % - bst_get('ImportDataOptions') : Import options for recordings
164 % - bst_get('ImportEegRawOptions') : Importation options for RAW EEG format
165 % - bst_get('BugReportOptions') : Bug reporter options
166 % - bst_get('DefaultSurfaceDisplay') : Default display options for surfaces (smooth, data threshold, sulci map)
167 % - bst_get('MagneticExtrapOptions') : Structure with the options for magnetic field extrapolation
168 % - bst_get('DefaultFreqBands')
169 % - bst_get('TimefreqOptions_morlet')
170 % - bst_get('TimefreqOptions_fft')
171 % - bst_get('TimefreqOptions_psd')
172 % - bst_get('TimefreqOptions_hilbert')
173 % - bst_get('OpenMEEGOptions')
174 % - bst_get('DuneuroOptions')
175 % - bst_get('GridOptions_headmodel')
176 % - bst_get('GridOptions_dipfit')
177 % - bst_get('UniformizeTimeSeriesScales') : {0,1} - If 1, the Y-axis of all the time series figures have the scale
178 % - bst_get('FlipYAxis') : {0,1} - If 1, the recordings are displayed with the negative values UP
179 % - bst_get('AutoScaleY') : {0,1} - If 1, the axis limits are updated when the figure is updated
180 % - bst_get('ShowXGrid') : {0,1} - If 1, show the XGrid in the time series figures
181 % - bst_get('ShowYGrid') : {0,1} - If 1, show the YGrid in the time series figures
182 % - bst_get('ShowZeroLines') : {0,1} - If 1, show the Y=0 lines in the columns view
183 % - bst_get('ShowEventsMode') : {'dot','line','none'}
184 % - bst_get('Resolution') : [resX,resY] fixed resolutions for X and Y axes
185 % - bst_get('FixedScaleY', Modality) : Struct with the scales to impose on the recordings for the selected modality
186 % - bst_get('XScale', XScale) : {'log', 'linear'}
187 % - bst_get('YScale', YScale) : {'log', 'linear'}
188 % - bst_get('UseSigProcToolbox') : Use Matlab's Signal Processing Toolbox when available
189 % - bst_get('RawViewerOptions', sFile) : Display options for RAW recordings, adapt for specific file
190 % - bst_get('RawViewerOptions') : Display options for RAW recordings
191 % - bst_get('TopoLayoutOptions') : Display options for 2DLayout display
192 % - bst_get('StatThreshOptions') : Options for online statistical thresholding
193 % - bst_get('ContactSheetOptions') : Display options for contact sheets
194 % - bst_get('ProcessOptions') : Options related with the data processing
195 % - bst_get('CustomColormaps') : Gets the list of user defined colormaps
196 % - bst_get('MriOptions') : Configuration for MRI display
197 % - bst_get('DigitizeOptions') : Digitizer options
198 % - bst_get('ReadOnly') : Read only interface
199 % - bst_get('NodelistOptions') : Structure with the options for file selection in the Process1 and Process2 panels
200 % - bst_get('ResizeFunction') : Get the appropriate resize function
201 % - bst_get('groot') : Get the root graphic object
202 % - bst_get('JFrame', hFig) : Get the underlying java frame for a Matlab figure
203 % - bst_get('LastPsdDisplayFunction') : Display option of measure for spectrum (log, power, magnitude, etc.)
204 % - bst_get('PlotlyCredentials') : Get the credentials and URL to connect to plot.ly server
205 % - bst_get('ExportBidsOptions') : Additional metadata for BIDS export
206 %
207 % SEE ALSO bst_set
208
209 % @=============================================================================
210 % This function is part of the Brainstorm software:
211 % https://neuroimage.usc.edu/brainstorm
212 %
213 % Copyright (c)2000-2020 University of Southern California & McGill University
214 % This software is distributed under the terms of the GNU General Public License
215 % as published by the Free Software Foundation. Further details on the GPLv3
216 % license can be found at http://www.gnu.org/copyleft/gpl.html.
217 %
218 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
219 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
220 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
221 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
222 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
223 %
224 % For more information type "brainstorm license" at command prompt.
225 % =============================================================================@
226 %
227 % Authors: Francois Tadel, 2008-2021
228 % Martin Cousineau, 2017
229
230 %% ==== PARSE INPUTS ====
231 global GlobalData;
232 if ((nargin >= 1) && ischar(varargin{1}))
233 contextName = varargin{1};
234 else
235 return
236 end
237 % Initialize returned variable
238 argout1 = [];
239 argout2 = [];
240 argout3 = [];
241 argout4 = [];
242 argout5 = [];
243
244 % Get required context structure
245 switch contextName
246 %% ==== SUBFUNCTIONS =====
247 case 'findFileInStudies'
248 [argout1, argout2, argout3] = findFileInStudies(varargin{2:end});
249
250 %% ==== BRAINSTORM CONFIGURATION ====
251 case 'Version'
252 argout1 = GlobalData.Program.Version;
253
254 case 'MatlabVersion'
255 if ~exist('version','builtin')
256 Version = 601;
257 else
258 % Get version number
259 str_vers = version();
260 vers = sscanf(str_vers, '%d.%d%*s');
261 if isempty(vers) || any(~isnumeric(vers)) || any(isnan(vers))
262 vers = 0;
263 end
264 Version = 100 * vers(1) + vers(2);
265 % Get release name
266 ipar = [find(str_vers == '('), find(str_vers == ')')];
267 end
268 argout1 = Version;
269
270 case 'MatlabReleaseName'
271 if ~exist('version','builtin')
272 Release = 'Matlab6';
273 else
274 % Get version number
275 str_vers = version();
276 % Get release name
277 ipar = [find(str_vers == '('), find(str_vers == ')')];
278 Release = str_vers(ipar(1)+1:ipar(2)-1);
279 end
280 argout1 = Release;
281
282 case 'JavaVersion'
283 strver = char(java.lang.System.getProperty('java.version'));
284 iDot = find(strver == '.');
285 if (length(iDot) < 2)
286 argout1 = str2num(strver);
287 else
288 argout1 = str2num(strver(1:iDot(2)-1));
289 end
290
291 case 'isJavacomponent'
292 % After Matlab 2019b, javacomponent() and JavaFrame property have been deprecated
293 argout1 = (bst_get('MatlabVersion') <= 906);
294
295 case 'SystemMemory'
296 maxvar = [];
297 totalmem = [];
298 if ispc && (bst_get('MatlabVersion') >= 706)
299 try
300 % Get memory info
301 usermem = memory();
302 maxvar = round(usermem.MaxPossibleArrayBytes / 1024 / 1024);
303 totalmem = round(usermem.MemAvailableAllArrays / 1024 / 1024);
304 catch
305 % Whatever...
306 end
307 end
308 argout1 = maxvar;
309 argout2 = totalmem;
310
311 case 'BrainstormHomeDir'
312 argout1 = GlobalData.Program.BrainstormHomeDir;
313 case 'BrainstormDbDir'
314 argout1 = GlobalData.DataBase.BrainstormDbDir;
315 case 'UserDir'
316 try
317 if ispc
318 userDir = getenv('USERPROFILE');
319 else
320 userDir = char(java.lang.System.getProperty('user.home'));
321 end
322 catch
323 userDir = '';
324 end
325 if isempty(userDir)
326 userDir = bst_get('BrainstormHomeDir');
327 end
328 argout1 = userDir;
329
330 case 'BrainstormUserDir'
331 bstUserDir = bst_fullfile(bst_get('UserDir'), '.brainstorm');
332 if ~isdir(bstUserDir)
333 res = mkdir(bstUserDir);
334 if ~res
335 error(['Cannot create Brainstorm user directory: "' bstUserDir '".']);
336 end
337 end
338 argout1 = bstUserDir;
339
340 case 'BrainstormTmpDir'
341 tmpDir = '';
342 isForcedDefault = ((nargin >= 2) && varargin{2});
343 % Default folder: userdir/tmp
344 defDir = bst_fullfile(bst_get('BrainstormUserDir'), 'tmp');
345 % If temporary directory is set in the preferences
346 if ~isForcedDefault && isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BrainstormTmpDir')
347 tmpDir = GlobalData.Preferences.BrainstormTmpDir;
348 end
349 % Else: use directory userdir/tmp
350 if isempty(tmpDir)
351 tmpDir = defDir;
352 end
353 % Create directory if it does not exist yet
354 if ~isdir(tmpDir)
355 res = mkdir(tmpDir);
356 if ~res && ~strcmp(tmpDir, defDir)
357 disp(['BST> Cannot create Brainstorm temporary directory: "' tmpDir '".']);
358 disp(['BST> Using default directory instead: "' defDir '".']);
359 % Create temporary folder
360 tmpDir = defDir;
361 if ~isdir(tmpDir)
362 res = mkdir(tmpDir);
363 else
364 res = 1;
365 end
366 end
367 % Error: cannot create any temporary folder
368 if ~res
369 error(['Cannot create Brainstorm temporary directory: "' tmpDir '".']);
370 end
371 end
372 argout1 = tmpDir;
373
374 case 'BrainstormDocDir'
375 docDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'doc');
376 if ~exist(docDir, 'file')
377 % Matlab compiler >= 2018b stores 'doc' under 'bst_javabuil'
378 docDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'bst_javabuil', 'doc');
379 if ~exist(docDir, 'file')
380 docDir = '';
381 disp('BST> Could not find "doc" folder.');
382 disp(['BST> BrainstormHomeDir = ' GlobalData.Program.BrainstormHomeDir]);
383 end
384 end
385 argout1 = docDir;
386
387 case 'BrainstormDefaultsDir'
388 defaultsDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'defaults');
389 if ~exist(defaultsDir, 'file')
390 % Matlab compiler >= 2018b stores 'defaults' under 'bst_javabuil'
391 defaultsDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'bst_javabuil', 'defaults');
392 if ~exist(defaultsDir, 'file')
393 defaultsDir = '';
394 disp('BST> Could not find "defaults" folder.');
395 disp(['BST> BrainstormHomeDir = ' GlobalData.Program.BrainstormHomeDir]);
396 end
397 end
398 argout1 = defaultsDir;
399
400 case 'UserReportsDir'
401 reportDir = bst_fullfile(bst_get('BrainstormUserDir'), 'reports');
402 if ~isdir(reportDir)
403 res = mkdir(reportDir);
404 if ~res
405 error(['Cannot create user reports directory: "' reportDir '".']);
406 end
407 end
408 argout1 = reportDir;
409
410 case 'UserMexDir'
411 mexDir = bst_fullfile(bst_get('BrainstormUserDir'), 'mex');
412 if ~isdir(mexDir)
413 res = mkdir(mexDir);
414 if ~res
415 error(['Cannot create Brainstorm mex-files directory: "' mexDir '".']);
416 end
417 end
418 argout1 = mexDir;
419
420 case 'UserProcessDir'
421 processDir = bst_fullfile(bst_get('BrainstormUserDir'), 'process');
422 if ~isdir(processDir)
423 res = mkdir(processDir);
424 if ~res
425 error(['Cannot create Brainstorm custom processes directory: "' processDir '".']);
426 end
427 end
428 argout1 = processDir;
429
430 case 'UserDefaultsDir'
431 defDir = bst_fullfile(bst_get('BrainstormUserDir'), 'defaults');
432 defDirAnat = bst_fullfile(defDir, 'anatomy');
433 defDirEeg = bst_fullfile(defDir, 'eeg');
434 if ~isdir(defDir)
435 res = mkdir(defDir);
436 if ~res
437 error(['Cannot create user templates directory: "' defDir '".']);
438 end
439 end
440 if ~isdir(defDirAnat)
441 res = mkdir(defDirAnat);
442 if ~res
443 error(['Cannot create user templates directory: "' defDirAnat '".']);
444 end
445 end
446 if ~isdir(defDirEeg)
447 res = mkdir(defDirEeg);
448 if ~res
449 error(['Cannot create user templates directory: "' defDirEeg '".']);
450 end
451 end
452 argout1 = defDir;
453
454 case 'UserPluginsDir'
455 pluginsDir = bst_fullfile(bst_get('BrainstormUserDir'), 'plugins');
456 if ~isdir(pluginsDir)
457 res = mkdir(pluginsDir);
458 if ~res
459 error(['Cannot create plugins directory: "' pluginsDir '".']);
460 end
461 end
462 argout1 = pluginsDir;
463
464 case 'BrainstormDbFile'
465 argout1 = bst_fullfile(bst_get('BrainstormUserDir'), 'brainstorm.mat');
466
467 %% ==== PROTOCOL ====
468 case 'iProtocol'
469 if isempty(GlobalData.DataBase.iProtocol)
470 argout1 = 0;
471 else
472 argout1 = GlobalData.DataBase.iProtocol;
473 end
474
475 case 'Protocol'
476 if ~isempty(GlobalData.DataBase.ProtocolInfo)
477 argout1 = find(strcmpi({GlobalData.DataBase.ProtocolInfo.Comment}, varargin{2}));
478 else
479 argout1 = [];
480 end
481
482 case {'ProtocolInfo', 'ProtocolSubjects', 'ProtocolStudies', 'isProtocolLoaded', 'isProtocolModified'}
483 argout2 = GlobalData.DataBase.iProtocol;
484 % No protocol: return empty matrix
485 if isempty(argout2) || ~isnumeric(argout2) || argout2 == 0
486 return;
487 end
488 % Check index integrity
489 if ((argout2 <= 0) || (argout2 > length(GlobalData.DataBase.ProtocolInfo))), warning('Brainstorm:InvalidIndex', 'Invalid index'), return, end
490 % Get requested protocol structure
491 argout1 = GlobalData.DataBase.(contextName)(argout2);
492
493
494 %% ==== STUDY ====
495 % Usage: [sStudy, iStudy] = bst_get('Study', StudyFileName)
496 % [sStudy, iStudy] = bst_get('Study')
497 % [sStudy, iStudy] = bst_get('Study', iStudies)
498 case 'Study'
499 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
500 return;
501 end
502 % Get list of current protocols
503 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
504 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
505 % Get list of current protocol studies
506 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
507 return;
508 end
509 % ===== PARSE INPUTS =====
510 if (nargin < 2)
511 % Call: bst_get('Study');
512 iStudies = ProtocolInfo.iStudy;
513 StudyFileName = [];
514 elseif (isnumeric(varargin{2}))
515 iStudies = varargin{2};
516 StudyFileName = [];
517 elseif (ischar(varargin{2}))
518 iStudies = [];
519 StudyFileName = strrep(varargin{2}, ProtocolInfo.STUDIES, '');
520 end
521 % Indices
522 iAnalysisStudy = -2; % CANNOT USE -1 => DISABLES SEARCH FUNCTIONS
523 iDefaultStudy = -3;
524 % Indices > 0: normal studies indiced in ProtocolStudies.Study array
525
526 % ===== GET STUDY BY INDEX =====
527 % Call: bst_get('Study', iStudies);
528 if ~isempty(iStudies)
529 argout1 = repmat(ProtocolStudies.DefaultStudy, 0);
530 % Get analysis study
531 iTargetAnalysis = find(iStudies == iAnalysisStudy);
532 if ~isempty(iTargetAnalysis)
533 argout1(iTargetAnalysis) = repmat(ProtocolStudies.AnalysisStudy, size(iTargetAnalysis));
534 argout2(iTargetAnalysis) = repmat(iAnalysisStudy, size(iTargetAnalysis));
535 end
536 % Get default study
537 iTargetDefault = find(iStudies == iDefaultStudy);
538 if ~isempty(iTargetDefault)
539 argout1(iTargetDefault) = repmat(ProtocolStudies.DefaultStudy, size(iTargetDefault));
540 argout2(iTargetDefault) = repmat(iDefaultStudy, size(iTargetDefault));
541 end
542 % Get normal studies
543 iTargetNormal = find((iStudies >= 1) & (iStudies <= length(ProtocolStudies.Study)));
544 if ~isempty(iTargetNormal)
545 argout1(iTargetNormal) = ProtocolStudies.Study(iStudies(iTargetNormal));
546 argout2(iTargetNormal) = iStudies(iTargetNormal);
547 end
548 % Error
549 if isempty(argout1)
550 GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol).iStudy = [];
551 end
552
553 % ===== GET STUDY BY FILENAME =====
554 % Call: bst_get('Study', StudyFileName);
555 elseif ~isempty(StudyFileName)
556 % NORMAL STUDY
557 iStudy = find(file_compare({ProtocolStudies.Study.FileName}, StudyFileName), 1);
558 % If a study is found : return it
559 if ~isempty(iStudy)
560 argout1 = ProtocolStudies.Study(iStudy);
561 argout2 = iStudy;
562 % DEFAULT STUDY
563 elseif ~isempty(ProtocolStudies.DefaultStudy) && file_compare({ProtocolStudies.DefaultStudy.FileName}, StudyFileName)
564 argout1 = ProtocolStudies.DefaultStudy;
565 argout2 = iDefaultStudy;
566 % ANALYSIS STUDY
567 elseif ~isempty(ProtocolStudies.AnalysisStudy) && file_compare({ProtocolStudies.AnalysisStudy.FileName}, StudyFileName)
568 argout1 = ProtocolStudies.AnalysisStudy;
569 argout2 = iAnalysisStudy;
570 end
571 else
572 return
573 end
574
575
576 %% ==== STUDY WITH SUBJECT FILE ====
577 % Usage : [sStudies, iStudies] = bst_get('StudyWithSubject', SubjectFile) : WITHOUT the system studies ('intra_subject', 'default_study')
578 % [sStudies, iStudies] = bst_get(..., 'intra_subject', 'default_study') : WITH the system studies: 'intra_subject' | 'default_study'
579 case 'StudyWithSubject'
580 % Parse inputs
581 if (nargin < 2) || ~ischar(varargin{2})
582 error('Invalid call to bst_get()');
583 end
584 if (nargin > 2)
585 IntraStudies = any(strcmpi(varargin(3:end), 'intra_subject'));
586 DefaultStudies = any(strcmpi(varargin(3:end), 'default_study'));
587 else
588 IntraStudies = 0;
589 DefaultStudies = 0;
590 end
591 SubjectFile = {varargin{2}};
592 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
593 return;
594 end
595 % Get list of current protocol description
596 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
597 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
598 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
599 return;
600 end
601
602 % Get default subject
603 sDefaultSubject = bst_get('Subject', 0);
604 % If SubjectFile is the default subject filename
605 if ~isempty(sDefaultSubject) && ~isempty(sDefaultSubject.FileName) && file_compare( SubjectFile{1}, sDefaultSubject.FileName)
606 % Get all the subjects files that use default anatomy
607 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
608 iSubjectUseDefaultAnat = find([ProtocolSubjects.Subject.UseDefaultAnat]);
609 if isempty(iSubjectUseDefaultAnat)
610 return
611 end
612 SubjectFile = {ProtocolSubjects.Subject(iSubjectUseDefaultAnat).FileName};
613 % Also updates inter-subject node
614 isInterSubject = 1;
615 else
616 isInterSubject = 0;
617 end
618 % Search all the current protocol's studies
619 iStudies = [];
620 for i=1:length(SubjectFile)
621 iStudies = [iStudies, find(file_compare({ProtocolStudies.Study.BrainStormSubject}, SubjectFile{i}))];
622 end
623 % Return results
624 if ~isempty(iStudies)
625 % Remove "analysis_intra" and "default_study" studies from list
626 if ~IntraStudies
627 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Name}, bst_get('DirAnalysisIntra'))) = [];
628 end
629 if ~DefaultStudies
630 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Name}, bst_get('DirDefaultStudy'))) = [];
631 end
632 % Return studies
633 argout1 = ProtocolStudies.Study(iStudies);
634 argout2 = iStudies;
635 else
636 argout1 = repmat(db_template('Study'), 0);
637 argout2 = [];
638 end
639 % Add inter-subject node, if needed
640 if isInterSubject
641 [sInterStudy, iInterStudy] = bst_get('AnalysisInterStudy');
642 argout1 = [argout1, sInterStudy];
643 argout2 = [argout2, iInterStudy];
644 end
645
646
647 %% ==== STUDY WITH CONDITION PATH ====
648 % USAGE: [sStudies, iStudies] = bst_get('StudyWithCondition', ConditionPath)
649 %
650 % INPUT: ConditionPath
651 % - 'SubjectName/conditionName' : Target condition for the specified subject
652 % - 'SubjectName/@intra' : Intra-subject condition for the subject
653 % - 'SubjectName/@default_study' : Default condition for the subject (where the subject's shared files are stored)
654 % - '*/conditionName' : Target condition for all the subjects
655 % - '@inter' : Inter-subject condition
656 % - '@default_study' : Protocol's default condition (where the protocol's shared files are stored)
657
658 case 'StudyWithCondition'
659 % Parse inputs
660 if (nargin ~= 2) || ~ischar(varargin{2})
661 error('Invalid call to bst_get()');
662 end
663 ConditionPath = varargin{2};
664 % Get list of current protocol description
665 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
666 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
667 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
668 return;
669 end
670
671 % ConditionPath = @inter
672 if strcmpi(ConditionPath, '@inter')
673 iStudy = -2;
674 argout2 = iStudy;
675 argout1 = bst_get('Study', iStudy);
676 % ConditionPath = @default_study
677 elseif strcmpi(ConditionPath, '@default_study')
678 iStudy = -3;
679 argout2 = iStudy;
680 argout1 = bst_get('Study', iStudy);
681 % ConditionPath = SubjectName/ConditionName
682 else
683 % Get subject and condition names
684 condSplit = str_split(ConditionPath);
685 if (length(condSplit) ~= 2)
686 error('Invalid condition path.');
687 end
688 SubjectName = condSplit{1};
689 ConditionName = condSplit{2};
690
691 % If first element is '*', search for condition in all the studies
692 if (SubjectName(1) == '*')
693 iStudies = 1:length(ProtocolStudies.Study);
694 % Else : search for condition only in studies that are linked to the subject specified in the ConditionPath
695 else
696 % Get subject
697 sSubject = bst_get('Subject', SubjectName, 1);
698 if isempty(sSubject)
699 return;
700 end
701 iStudies = find(file_compare({ProtocolStudies.Study.BrainStormSubject}, sSubject.FileName));
702 end
703 % Nothing to search
704 if isempty(iStudies)
705 return
706 end
707
708 % Search all the current protocol's studies
709 iStudies = iStudies(cellfun(@(c)isequal(ConditionName, c), [ProtocolStudies.Study(iStudies).Condition]));
710 % Return results
711 if ~isempty(iStudies)
712 % Remove "analysis_intra" and "default_study" studies from list
713 if ~strcmpi(ConditionName, '@intra')
714 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Condition}, bst_get('DirAnalysisIntra'))) = [];
715 end
716 if ~strcmpi(ConditionName, '@default_study')
717 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Condition}, bst_get('DirDefaultStudy'))) = [];
718 end
719 % Sort by subject
720 if (length(iStudies) > 1)
721 SubjNameList = cell(1,length(iStudies));
722 % For each study, get subject name
723 for i = 1:length(iStudies)
724 sSubject = bst_get('Subject', ProtocolStudies.Study(iStudies(i)).BrainStormSubject);
725 SubjNameList{i} = sSubject.Name;
726 end
727 % Sort subjects names
728 [sortSubjList, iSort] = sort(SubjNameList);
729 % Apply same sorting to studies
730 iStudies = iStudies(iSort);
731 end
732 % Return studies
733 argout1 = ProtocolStudies.Study(iStudies);
734 argout2 = iStudies;
735 else
736 argout1 = repmat(db_template('Study'), 0);
737 argout2 = [];
738 end
739 end
740
741 %% ==== CHANNEL STUDIES WITH SUBJECT ====
742 % Usage: iStudies = bst_get('ChannelStudiesWithSubject', iSubjects, 'NoIntra')
743 case 'ChannelStudiesWithSubject'
744 % Parse inputs
745 if (nargin >= 2) && isnumeric(varargin{2})
746 iSubjects = varargin{2};
747 else
748 error('Invalid call to bst_get()');
749 end
750 if (nargin == 3) && strcmpi(varargin{3}, 'NoIntra')
751 NoIntra = 1;
752 else
753 NoIntra = 0;
754 end
755 % Process all subjects
756 iStudies = [];
757 for i=1:length(iSubjects)
758 iSubject = iSubjects(i);
759 sSubject = bst_get('Subject', iSubject, 1);
760 % No subject: error
761 if isempty(sSubject)
762 continue
763 % If subject uses default channel file
764 elseif (sSubject.UseDefaultChannel ~= 0)
765 % Get default study for this subject
766 [tmp___, iStudiesNew] = bst_get('DefaultStudy', iSubject);
767 iStudies = [iStudies, iStudiesNew];
768 % Else: get all the studies belonging to this subject
769 else
770 if NoIntra
771 [tmp___, iStudiesNew] = bst_get('StudyWithSubject', sSubject.FileName);
772 else
773 [tmp___, iStudiesNew] = bst_get('StudyWithSubject', sSubject.FileName, 'intra_subject');
774 end
775 iStudies = [iStudies, iStudiesNew];
776 end
777 end
778 argout1 = iStudies;
779
780
781 %% ==== STUDIES COUNT ====
782 % Usage: [nbStudies] = bst_get('StudyCount')
783 case 'StudyCount'
784 % Nothing
785 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
786 argout1 = 0;
787 return;
788 end
789 % Get list of current protocol studies
790 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
791 argout1 = length(ProtocolStudies.Study);
792
793 %% ==== SUBJECTS COUNT ====
794 % Usage: [nbSubjects] = bst_get('SubjectCount')
795 case 'SubjectCount'
796 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
797 argout1 = 0;
798 return;
799 end
800 % Get list of current protocol studies
801 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
802 argout1 = length(ProtocolSubjects.Subject);
803
804 %% ==== NORMALIZED SUBJECT ====
805 case 'NormalizedSubject'
806 % Get normalized subject name
807 normSubjName = 'Group_analysis';
808 % Try to get normalized subject
809 [sNormSubj, iNormSubj] = bst_get('Subject', normSubjName, 0);
810 % If normalized subject does not exist: create it
811 if isempty(sNormSubj)
812 % Always use default anatomy
813 UseDefaultAnat = 1;
814 % If all the subjects use a global channel file: Use global default as well
815 if ~isempty(GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol).Subject) && ...
816 all([GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol).Subject.UseDefaultChannel] == 2)
817 UseDefaultChannel = 2;
818 else
819 UseDefaultChannel = 1;
820 end
821 % Create subject
822 [sNormSubj, iNormSubj] = db_add_subject(normSubjName, [], UseDefaultAnat, UseDefaultChannel);
823 % Get full subject structure
824 [sNormSubj, iNormSubj] = bst_get('Subject', normSubjName, 0);
825 end
826 argout1 = sNormSubj;
827 argout2 = iNormSubj;
828
829
830 %% ==== ANALYSIS STUDY (INTRA) ====
831 % Usage: [sAnalStudy, iAnalStudy] = bst_get('AnalysisIntraStudy', iSubject)
832 case 'AnalysisIntraStudy'
833 % Parse inputs
834 if (nargin == 2) && isnumeric(varargin{2})
835 iSubject = varargin{2};
836 else
837 error('Invalid call to bst_get()');
838 end
839 % Get subject
840 sSubject = bst_get('Subject', iSubject, 1);
841 % Get studies related to subject
842 [sSubjStudies, iSubjStudies] = bst_get('StudyWithSubject', sSubject.FileName, 'intra_subject');
843 % Look for the 'AnalysisIntra' study
844 iFound = find(cellfun(@(c)ismember(bst_get('DirAnalysisIntra'), c), {sSubjStudies.Condition}));
845 iAnalStudy = iSubjStudies(iFound);
846 sAnalStudy = sSubjStudies(iFound);
847 % Return found structure
848 argout1 = sAnalStudy;
849 argout2 = iAnalStudy;
850
851
852 %% ==== ANALYSIS STUDY (INTER) ====
853 % Usage: [sAnalStudyInter, iAnalStudyInter] = bst_get('AnalysisInterStudy')
854 case 'AnalysisInterStudy'
855 iAnalStudyInter = -2;
856 [argout1, argout2] = bst_get('Study', iAnalStudyInter);
857
858
859 %% ==== DEFAULT STUDY ====
860 % Usage: [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy', iSubject)
861 % [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy') : iSubject=0
862 % [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy', SubjectFile)
863 case 'DefaultStudy'
864 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
865 return;
866 end
867 % Parse inputs
868 if (nargin == 1)
869 iSubject = 0;
870 elseif (nargin == 2) && isnumeric(varargin{2})
871 iSubject = varargin{2};
872 elseif (nargin == 2) && ischar(varargin{2})
873 SubjectFile = varargin{2};
874 % Get subject attached to study
875 [sSubject, iSubject] = bst_get('Subject', SubjectFile, 1);
876 if isempty(sSubject) || ~sSubject.UseDefaultChannel
877 return;
878 end
879 else
880 error('Invalid call to bst_get()');
881 end
882 % === DEFAULT SUBJECT ===
883 % => Return global default study
884 if (iSubject == 0)
885 % Get protocol's studies
886 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
887 % Return Global default study
888 argout1 = ProtocolStudies.DefaultStudy;
889 argout2 = -3;
890 % === NORMAL SUBJECT ===
891 else
892 % Get subject
893 sSubject = bst_get('Subject', iSubject, 1);
894 % === GLOBAL DEFAULT STUDY ===
895 if sSubject.UseDefaultChannel == 2
896 % Get protocol's studies
897 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
898 % Return Global default study
899 argout1 = ProtocolStudies.DefaultStudy;
900 argout2 = -3;
901 % === SUBJECT'S DEFAULT STUDY ===
902 elseif sSubject.UseDefaultChannel == 1
903 % Get studies related to subject
904 [sSubjStudies, iSubjStudies] = bst_get('StudyWithSubject', sSubject.FileName, 'default_study');
905 % Look for the 'DefaultStudy' study
906 iFound = find(cellfun(@(c)ismember(bst_get('DirDefaultStudy'), c), {sSubjStudies.Condition}));
907 iDefaultStudy = iSubjStudies(iFound);
908 sDefaultStudy = sSubjStudies(iFound);
909 % Return found structure
910 argout1 = sDefaultStudy;
911 argout2 = iDefaultStudy;
912 end
913 end
914
915
916
917 %% ==== SUBJECT ====
918 % Usage : [sSubject, iSubject] = bst_get('Subject', iSubject, isRaw)
919 % [sSubject, iSubject] = bst_get('Subject', SubjectFileName, isRaw);
920 % [sSubject, iSubject] = bst_get('Subject', SubjectName, isRaw);
921 % [sSubject, iSubject] = bst_get('Subject');
922 % If isRaw is set: force to return the real brainstormsubject description
923 % (ignoring wether it uses protocol's default anatomy or not)
924 case 'Subject'
925 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
926 return;
927 end
928 % Get list of current protocol subjects
929 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
930 sSubject = [];
931 SubjectName = [];
932 SubjectFileName = [];
933 % ISRAW parameter
934 if (nargin < 3)
935 isRaw = 0;
936 else
937 isRaw = varargin{3};
938 end
939 % Call: bst_get('subject', iSubject, isRaw);
940 if (nargin >= 2) && isnumeric(varargin{2})
941 iSubject = varargin{2};
942 if (iSubject > length(ProtocolSubjects.Subject))
943 error('Invalid subject indice.');
944 end
945 % If required subject is default subject (iSubject = 0)
946 if (iSubject == 0)
947 % Default subject available
948 if ~isempty(ProtocolSubjects.DefaultSubject)
949 sSubject = ProtocolSubjects.DefaultSubject;
950 % Default subject not available
951 else
952 return
953 end
954 % Normal subject
955 else
956 sSubject = ProtocolSubjects.Subject(iSubject);
957 end
958
959 % Call: bst_get('subject', SubjectFileName, isRaw);
960 % Call: bst_get('subject', SubjectName, isRaw);
961 elseif (nargin >= 2) && isempty(varargin{2})
962 % If study name is empty: use DefaultSubject
963 SubjectFileName = ProtocolSubjects.DefaultSubject.FileName;
964 elseif (nargin >= 2) && (ischar(varargin{2}))
965 [fName, fBase, fExt] = bst_fileparts(varargin{2});
966 % Argument is a Matlab .mat filename
967 if strcmpi(fExt, '.mat')
968 SubjectFileName = varargin{2};
969 % Else : assume argument is a directory
970 else
971 SubjectName = file_standardize(varargin{2});
972 end
973
974 % Call: bst_get('subject'); => looking for current subject
975 elseif (nargin < 2)
976 % Get current subject filename in current study
977 sStudy = bst_get('Study');
978 if isempty(sStudy)
979 return
980 end
981 SubjectFileName = sStudy.BrainStormSubject;
982 % If study's subject is not defined, get DefaultSubject
983 if isempty(SubjectFileName) && ~isempty(ProtocolSubjects.DefaultSubject)
984 SubjectFileName = ProtocolSubjects.DefaultSubject.FileName;
985 end
986 else
987 error('Invalid call to bst_get()');
988 end
989
990 % If Subject is defined by its filename/name
991 if isempty(sSubject)
992 % Look in Default Subject
993 if ~isempty(ProtocolSubjects.DefaultSubject) && (file_compare(ProtocolSubjects.DefaultSubject.FileName, SubjectFileName) ...
994 || strcmpi(ProtocolSubjects.DefaultSubject.Name, SubjectName))
995 sSubject = ProtocolSubjects.DefaultSubject;
996 iSubject = 0;
997 % If not found : find target subject file name in normal subjects
998 elseif ~isempty(SubjectFileName)
999 iSubject = find(file_compare({ProtocolSubjects.Subject.FileName}, SubjectFileName), 1);
1000 sSubject = ProtocolSubjects.Subject(iSubject);
1001 elseif ~isempty(SubjectName)
1002 iSubject = find(file_compare({ProtocolSubjects.Subject.Name}, SubjectName), 1);
1003 sSubject = ProtocolSubjects.Subject(iSubject);
1004 else
1005 error('Subject name not specified.');
1006 end
1007 end
1008
1009 % Return found subject
1010 if ~isempty(iSubject) && ~isempty(sSubject)
1011 % If subject uses default subject
1012 if sSubject.UseDefaultAnat && ~isRaw && ~isempty(ProtocolSubjects.DefaultSubject) && ~isempty(ProtocolSubjects.DefaultSubject.FileName)
1013 % Return default subject (WITH REAL SUBJECT'S NAME)
1014 argout1 = ProtocolSubjects.DefaultSubject;
1015 argout1.Name = sSubject.Name;
1016 argout1.UseDefaultAnat = sSubject.UseDefaultAnat;
1017 argout1.UseDefaultChannel = sSubject.UseDefaultChannel;
1018 argout2 = iSubject;
1019 % Else, return found subject
1020 else
1021 argout1 = sSubject;
1022 argout2 = iSubject;
1023 end
1024 end
1025
1026
1027 %% ==== SURFACE FILE ====
1028 % Usage : [sSubject, iSubject, iSurface] = bst_get('SurfaceFile', SurfaceFile)
1029 case 'SurfaceFile'
1030 % No protocol in database
1031 if isempty(GlobalData) || isempty(GlobalData.DataBase) || isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1032 return;
1033 end
1034 % Get list of current protocol subjects
1035 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
1036 if isempty(ProtocolSubjects)
1037 return
1038 end;
1039
1040 % Parse inputs
1041 if (nargin == 2)
1042 SurfaceFile = varargin{2};
1043 else
1044 error('Invalid call to bst_get().');
1045 end
1046
1047 % Remove SUBJECTS path from SurfaceFile
1048 SurfaceFile = file_short(SurfaceFile);
1049 % Look for surface file in DefaultSubject
1050 if ~isempty(ProtocolSubjects.DefaultSubject)
1051 % Find the first surface that matches the SurfaceFile
1052 iSurface = find(file_compare(SurfaceFile, {ProtocolSubjects.DefaultSubject.Surface.FileName}), 1);
1053 % If a surface was found in default subject : return it
1054 if ~isempty(iSurface)
1055 argout1 = ProtocolSubjects.DefaultSubject;
1056 argout2 = 0;
1057 argout3 = iSurface;
1058 return
1059 end
1060 end
1061 % Look for surface file in all the surfaces of all subjects
1062 for iSubj = 1:length(ProtocolSubjects.Subject)
1063 % Find the first surface that matches the SurfaceFile
1064 iSurface = find(file_compare(SurfaceFile, {ProtocolSubjects.Subject(iSubj).Surface.FileName}), 1);
1065 % If a surface was found in current subject : return it
1066 if ~isempty(iSurface)
1067 argout1 = ProtocolSubjects.Subject(iSubj);
1068 argout2 = iSubj;
1069 argout3 = iSurface;
1070 return
1071 end
1072 end
1073
1074
1075 %% ==== SURFACE FILE BY TYPE ====
1076 % Usage : [sSurface, iSurface] = bst_get('SurfaceFileByType', iSubject, SurfaceType)
1077 % [sSurface, iSurface] = bst_get('SurfaceFileByType', SubjectFile, SurfaceType)
1078 % [sSurface, iSurface] = bst_get('SurfaceFileByType', SurfaceFile, SurfaceType)
1079 % [sSurface, iSurface] = bst_get('SurfaceFileByType', MriFile, SurfaceType)
1080 % [sSurface, iSurface] = bst_get('SurfaceFileByType', ..., SurfaceType, isDefaultOnly)
1081 case 'SurfaceFileByType'
1082 % By default: return only the default surfaces of the category
1083 if (nargin < 4)
1084 isDefaultOnly = 1;
1085 else
1086 isDefaultOnly = varargin{4};
1087 end
1088 % Get subject
1089 if isempty(varargin{2})
1090 % Get default subject
1091 sSubject = bst_get('Subject', 0);
1092 elseif ischar(varargin{2})
1093 FileName = varargin{2};
1094 sSubject = bst_get('AnyFile', FileName);
1095 else
1096 iSubject = varargin{2};
1097 sSubject = bst_get('Subject', iSubject);
1098 end
1099 % Error handling
1100 if isempty(sSubject)
1101 disp('BST> Warning: Subject not found.');
1102 return;
1103 elseif isempty(sSubject.Surface)
1104 return;
1105 end
1106 SurfaceType = varargin{3};
1107
1108 % === RETURN ONLY DEFAULTS ===
1109 if isDefaultOnly
1110 % Look for required surface type
1111 field = ['i' SurfaceType];
1112 if ~isfield(sSubject, field) || isempty(sSubject.(field))
1113 return
1114 end
1115 argout1 = sSubject.Surface(sSubject.(field));
1116 argout2 = sSubject.(field);
1117 % === RETURN ALL THE SURFACES ===
1118 else
1119 % Build the list of tagged surfaces
1120 fileTag = ['_' lower(SurfaceType)];
1121 iTargetList = find(cellfun(@(c)~isempty(strfind(c, fileTag)), {sSubject.Surface.FileName}));
1122 % Put the default cortex on top of the list
1123 iDefaults = intersect([sSubject.iCortex, sSubject.iScalp, sSubject.iInnerSkull, sSubject.iOuterSkull, sSubject.iFibers, sSubject.iFEM], iTargetList);
1124 if ~isempty(iDefaults)
1125 iTargetList = [iDefaults, setdiff(iTargetList, iDefaults)];
1126 end
1127 % Return all cortex surfaces
1128 argout1 = sSubject.Surface(iTargetList);
1129 argout2 = iTargetList;
1130 end
1131
1132
1133 %% ==== MRI FILE ====
1134 % Usage : [sSubject, iSubject, iMri] = bst_get('MriFile', MriFile)
1135 case 'MriFile'
1136 % No protocol in database
1137 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1138 return;
1139 end
1140 % Get list of current protocol subjects
1141 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
1142 if isempty(ProtocolSubjects)
1143 return
1144 end
1145
1146 % Parse inputs
1147 if (nargin == 2)
1148 MriFile = varargin{2};
1149 else
1150 error('Invalid call to bst_get().');
1151 end
1152
1153 % Remove SUBJECTS path from MriFile
1154 MriFile = file_short(MriFile);
1155 % Look for MRI file in DefaultSubject
1156 if ~isempty(ProtocolSubjects.DefaultSubject)
1157 % Find the first MRI that matches the MriFile
1158 iMri = find(file_compare(MriFile, {ProtocolSubjects.DefaultSubject.Anatomy.FileName}), 1);
1159 % If a MRI was found in default subject : return it
1160 if ~isempty(iMri)
1161 argout1 = ProtocolSubjects.DefaultSubject;
1162 argout2 = 0;
1163 argout3 = iMri;
1164 return
1165 end
1166 end
1167 % Look for MRI file in all the MRIs of all subjects
1168 for iSubj = 1:length(ProtocolSubjects.Subject)
1169 % Find the first MRI that matches the MriFile
1170 iMri = find(file_compare(MriFile, {ProtocolSubjects.Subject(iSubj).Anatomy.FileName}), 1);
1171 % If a MRI was found in current subject : return it
1172 if ~isempty(iMri)
1173 argout1 = ProtocolSubjects.Subject(iSubj);
1174 argout2 = iSubj;
1175 argout3 = iMri;
1176 return
1177 end
1178 end
1179
1180
1181 %% ==== CHANNEL FILE ====
1182 % Usage: [sStudy, iStudy, iChannel] = bst_get('ChannelFile', ChannelFile)
1183 case 'ChannelFile'
1184 % No protocol in database
1185 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1186 return;
1187 end
1188 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1189 % Parse inputs
1190 if (nargin == 2)
1191 ChannelFile = varargin{2};
1192 ChannelFile = strrep(ChannelFile, ProtocolInfo.STUDIES, '');
1193 else
1194 error('Invalid call to bst_get().');
1195 end
1196 % Look for Channel file in all the surfaces of all subjects
1197 [argout1, argout2, argout3] = findFileInStudies('Channel', 'FileName', ChannelFile);
1198
1199
1200 %% ==== CHANNEL FILE FOR STUDY ====
1201 % Usage: [ChannelFile, sStudy, iStudy] = bst_get('ChannelFileForStudy', StudyFile/DataFile)
1202 case 'ChannelFileForStudy'
1203 % Parse inputs
1204 if (nargin == 2)
1205 StudyFile = varargin{2};
1206 else
1207 error('Invalid call to bst_get().');
1208 end
1209 % Get study in database
1210 [sStudy, iStudy] = bst_get('Study', StudyFile);
1211 % If data file instead on Study file
1212 if isempty(sStudy)
1213 [sStudy, iStudy] = bst_get('AnyFile', StudyFile);
1214 end
1215 sChannel = bst_get('ChannelForStudy', iStudy);
1216 if ~isempty(sChannel)
1217 argout1 = sChannel.FileName;
1218 argout2 = sStudy;
1219 argout3 = iStudy;
1220 else
1221 argout1 = [];
1222 end
1223
1224
1225 %% ==== CHANNEL STRUCT FOR STUDY ====
1226 % Usage: [sChannel, iChanStudy] = bst_get('ChannelForStudy', iStudies)
1227 case 'ChannelForStudy'
1228 % Parse inputs
1229 if (nargin == 2)
1230 iStudies = varargin{2};
1231 else
1232 error('Invalid call to bst_get().');
1233 end
1234 iChanStudies = [];
1235 sListChannel = [];
1236 for i = 1:length(iStudies)
1237 % Get study
1238 iStudy = iStudies(i);
1239 sStudy = bst_get('Study', iStudy);
1240 if isempty(sStudy)
1241 continue;
1242 end
1243 iChanStudy = iStudy;
1244 % === Analysis-Inter node ===
1245 iAnalysisInter = -2;
1246 iGlobalDefaultStudy = -3;
1247 if (iStudy == iAnalysisInter)
1248 % If no channel file is defined in 'Analysis-intra' node: look in
1249 if isempty(sStudy.Channel)
1250 % Get global default study
1251 sStudy = bst_get('Study', iGlobalDefaultStudy);
1252 iChanStudy = iGlobalDefaultStudy;
1253 end
1254 % === All other nodes ===
1255 else
1256 % Get subject attached to study
1257 [sSubject, iSubject] = bst_get('Subject', sStudy.BrainStormSubject, 1);
1258 if isempty(sSubject)
1259 return;
1260 end
1261 % Subject uses default channel/headmodel
1262 if (sSubject.UseDefaultChannel ~= 0)
1263 [sStudy, iChanStudy] = bst_get('DefaultStudy', iSubject);
1264 if isempty(sStudy)
1265 return
1266 end
1267 end
1268 end
1269 iChanStudies = [iChanStudies, iChanStudy];
1270 sListChannel = [sListChannel, sStudy.Channel];
1271 end
1272 % Return Channel structure
1273 argout1 = sListChannel;
1274 argout2 = iChanStudies;
1275
1276 %% ==== CHANNEL MODALITIES =====
1277 % Usage: [Modalities, DispMod, DefMod] = bst_get('ChannelModalities', ChannelFile)
1278 % [Modalities, DispMod, DefMod] = bst_get('ChannelModalities', DataFile/ResultsFile/TimefreqFile...)
1279 case 'ChannelModalities'
1280 % Get input file
1281 [sStudy, iStudy, iItem, DataType, sItem] = bst_get('AnyFile', varargin{2});
1282 % If channel file
1283 if strcmpi(DataType, 'channel')
1284 sChannel = sItem;
1285 else
1286 sChannel = bst_get('ChannelForStudy', iStudy);
1287 end
1288 % Return modalities
1289 if ~isempty(sChannel)
1290 % Get all modalities
1291 if ~isempty(sChannel.DisplayableSensorTypes)
1292 % Return the displayable sensors on top of the list
1293 argout1 = cat(2, sChannel.DisplayableSensorTypes, setdiff(sChannel.Modalities, sChannel.DisplayableSensorTypes));
1294 else
1295 argout1 = sChannel.Modalities;
1296 end
1297 % Get only sensors that have spatial representation
1298 argout2 = sChannel.DisplayableSensorTypes;
1299 % Default candidates
1300 if ~isempty(argout2)
1301 defList = argout2;
1302 else
1303 defList = argout1;
1304 end
1305 if isempty(defList)
1306 return;
1307 end
1308 % Remove EDF and BDF from the default list
1309 defList = setdiff(defList, {'EDF','BDF','KDF'});
1310 % Get default modality
1311 if ismember('SEEG', defList)
1312 argout3 = 'SEEG';
1313 elseif ismember('ECOG', defList)
1314 argout3 = 'ECOG';
1315 elseif any(ismember({'MEG','MEG GRAD','MEG MAG'}, defList))
1316 argout3 = 'MEG';
1317 elseif ismember('EEG', defList)
1318 argout3 = 'EEG';
1319 elseif ismember('NIRS', defList)
1320 argout3 = 'NIRS';
1321 else
1322 argout3 = defList{1};
1323 end
1324 % Place the default on top of the lists
1325 if ismember(argout3, argout1)
1326 argout1(strcmpi(argout1, argout3)) = [];
1327 argout1 = cat(2, argout3, argout1);
1328 end
1329 if ismember(argout3, argout2)
1330 argout2(strcmpi(argout2, argout3)) = [];
1331 argout2 = cat(2, argout3, argout2);
1332 end
1333 else
1334 argout1 = [];
1335 end
1336
1337
1338 %% ==== TIMEFREQ DISPLAY MODALITIES ====
1339 % Usage: DisplayMod = bst_get('TimefreqDisplayModalities', TimefreqFile)
1340 case 'TimefreqDisplayModalities'
1341 TimefreqFile = varargin{2};
1342 % Load sensor names from file
1343 TimefreqMat = in_bst_timefreq(TimefreqFile, 0, 'RowNames');
1344 % Get channel file
1345 ChannelFile = bst_get('ChannelFileForStudy', TimefreqFile);
1346 if isempty(ChannelFile)
1347 return;
1348 end
1349 % Load channel file
1350 ChannelMat = load(file_fullpath(ChannelFile), 'Channel');
1351 % Get channels that are present in the file
1352 [tmp__,I,J] = intersect({ChannelMat.Channel.Name}, TimefreqMat.RowNames);
1353 FileMod = unique({ChannelMat.Channel(I).Type});
1354 % Check if only one type of gradiometer is selected
1355 if isequal(FileMod, {'MEG GRAD'}) && all(cellfun(@(c)(c(end)=='2'), {ChannelMat.Channel(I).Name}))
1356 argout1 = {'MEG GRAD2'};
1357 elseif isequal(FileMod, {'MEG GRAD'}) && all(cellfun(@(c)(c(end)=='3'), {ChannelMat.Channel(I).Name}))
1358 argout1 = {'MEG GRAD3'};
1359 % Keep only the modalities that can be displayed (as topography)
1360 else
1361 argout1 = intersect(FileMod, {'MEG','MEG GRAD','MEG MAG','EEG','ECOG','SEEG','NIRS'});
1362 end
1363
1364
1365 %% ==== CHANNEL DEVICE ====
1366 % Usage: Device = bst_get('ChannelDevice', ChannelFile)
1367 case 'ChannelDevice'
1368 ChannelFile = varargin{2};
1369 if ~isempty(strfind(ChannelFile, 'vectorview306'))
1370 Device = 'Vectorview306';
1371 elseif ~isempty(strfind(ChannelFile, 'ctf_acc1'))
1372 Device = 'CTF';
1373 elseif ~isempty(strfind(ChannelFile, '4d_acc1'))
1374 Device = '4D';
1375 elseif ~isempty(strfind(ChannelFile, 'babysquid'))
1376 Device = 'BabySQUID';
1377 elseif ~isempty(strfind(ChannelFile, 'babymeg'))
1378 Device = 'BabyMEG';
1379 elseif ~isempty(strfind(ChannelFile, 'kit'))
1380 Device = 'KIT';
1381 elseif ~isempty(strfind(ChannelFile, 'ricoh'))
1382 Device = 'RICOH';
1383 elseif ~isempty(strfind(ChannelFile, 'kriss'))
1384 Device = 'KRISS';
1385 elseif ~isempty(strfind(ChannelFile, 'nirsbrs'))
1386 Device = 'NIRS-BRS';
1387 else
1388 Device = '';
1389 end
1390 argout1 = Device;
1391
1392
1393 %% ==== HEADMODEL STRUCT FOR STUDY ====
1394 % Usage: [sHeadModel] = bst_get('HeadModelForStudy', iStudy)
1395 case 'HeadModelForStudy'
1396 % Parse inputs
1397 if (nargin == 2)
1398 iStudy = varargin{2};
1399 else
1400 error('Invalid call to bst_get().');
1401 end
1402 % Get study
1403 sStudy = bst_get('Study', iStudy);
1404 % === Analysis-Inter node ===
1405 iAnalysisInter = -2;
1406 iGlobalDefaultStudy = -3;
1407 if (iStudy == iAnalysisInter)
1408 % If no channel file is defined in 'Analysis-intra' node: look in
1409 if isempty(sStudy.iHeadModel)
1410 % Get global default study
1411 sStudy = bst_get('Study', iGlobalDefaultStudy);
1412 end
1413 % === All other nodes ===
1414 else
1415 % Get subject attached to study
1416 [sSubject, iSubject] = bst_get('Subject', sStudy.BrainStormSubject, 1);
1417 if isempty(sSubject)
1418 return;
1419 end
1420 % Subject uses default channel/headmodel
1421 if (sSubject.UseDefaultChannel ~= 0)
1422 sStudy = bst_get('DefaultStudy', iSubject);
1423 if isempty(sStudy)
1424 return
1425 end
1426 end
1427 end
1428 % Return HeadModel structure
1429 if ~isempty(sStudy.iHeadModel)
1430 argout1 = sStudy.HeadModel(sStudy.iHeadModel(1));
1431 else
1432 argout1 = [];
1433 end
1434
1435
1436 %% ==== HEADMODEL FILE ====
1437 % Usage: [sStudy, iStudy, iHeadModel] = bst_get('HeadModelFile', HeadModelFile, iStudies)
1438 % [sStudy, iStudy, iHeadModel] = bst_get('HeadModelFile', HeadModelFile)
1439 case 'HeadModelFile'
1440 % No protocol in database
1441 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1442 return;
1443 end
1444 % Input #2: HeadModelFile
1445 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1446 HeadModelFile = varargin{2};
1447 HeadModelFile = strrep(HeadModelFile, ProtocolInfo.STUDIES, '');
1448 % Input #3: iStudies
1449 if (nargin < 3)
1450 iStudies = [];
1451 else
1452 iStudies = varargin{3};
1453 end
1454 % Look for surface file in all the surfaces of all subjects
1455 [argout1, argout2, argout3] = findFileInStudies('HeadModel', 'FileName', HeadModelFile, iStudies);
1456
1457 %% ==== NOISECOV FILE ====
1458 % Usage: [sStudy, iStudy, iNoiseCov] = bst_get('NoiseCovFile', NoiseCovFile, iStudies)
1459 % [sStudy, iStudy, iNoiseCov] = bst_get('NoiseCovFile', NoiseCovFile)
1460 % Usage: [sStudy, iStudy, iNoiseCov] = bst_get('DataCovFile', NoiseCovFile, iStudies)
1461 % [sStudy, iStudy, iNoiseCov] = bst_get('DataCovFile', NoiseCovFile)
1462 case {'NoiseCovFile', 'DataCovFile'}
1463 % No protocol in database
1464 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1465 return;
1466 end
1467 % Input #2: NoiseCovFile
1468 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1469 NoiseCovFile = varargin{2};
1470 NoiseCovFile = strrep(NoiseCovFile, ProtocolInfo.STUDIES, '');
1471 % Input #3: iStudies
1472 if (nargin < 3)
1473 iStudies = [];
1474 else
1475 iStudies = varargin{3};
1476 end
1477 % Look for surface file in all the surfaces of all subjects
1478 [argout1, argout2, argout3] = findFileInStudies('NoiseCov', 'FileName', NoiseCovFile, iStudies);
1479
1480
1481 %% ==== DATA FILE ====
1482 % Usage: [sStudy, iStudy, iData] = bst_get('DataFile', DataFile, iStudies)
1483 % [sStudy, iStudy, iData] = bst_get('DataFile', DataFile)
1484 case 'DataFile'
1485 % No protocol in database
1486 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1487 return;
1488 end
1489 % Input #2: DataFile
1490 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1491 DataFile = varargin{2};
1492 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1493 % Input #3: iStudies
1494 if (nargin < 3)
1495 iStudies = [];
1496 else
1497 iStudies = varargin{3};
1498 end
1499 % Look for file in all the studies
1500 [argout1, argout2, argout3] = findFileInStudies('Data', 'FileName', DataFile, iStudies);
1501
1502
1503 %% ==== DATA FOR DATA LIST ====
1504 % Usage: [iFoundData] = bst_get('DataForDataList', iStudy, DataListName)
1505 case 'DataForDataList'
1506 iStudy = varargin{2};
1507 DataListName = varargin{3};
1508 % Get study structure
1509 sStudy = bst_get('Study', iStudy);
1510 % Get all the data files held by this datalist
1511 listComments = cellfun(@(c)deblank(str_remove_parenth(c)), {sStudy.Data.Comment}, 'UniformOutput', 0);
1512 iFoundData = find(strcmp(listComments, DataListName));
1513 % Return found data files
1514 argout1 = iFoundData;
1515
1516 %% ==== MATRIX FOR MATRIX LIST ====
1517 % Usage: [iFoundMatrix] = bst_get('MatrixForMatrixList', iStudy, MatrixListName)
1518 case 'MatrixForMatrixList'
1519 iStudy = varargin{2};
1520 MatrixListName = varargin{3};
1521 % Get study structure
1522 sStudy = bst_get('Study', iStudy);
1523 % Get all the matrix files held by this datalist
1524 listComments = cellfun(@(c)deblank(str_remove_parenth(c)), {sStudy.Matrix.Comment}, 'UniformOutput', 0);
1525 iFoundMatrix = find(strcmp(listComments, MatrixListName));
1526 % Return found matrix files
1527 argout1 = iFoundMatrix;
1528
1529
1530 %% ==== DATA FOR STUDY (INCLUDING SHARED STUDIES) ====
1531 % Usage: [iStudies, iDatas] = bst_get('DataForStudy', iStudy)
1532 case 'DataForStudy'
1533 % Get target study
1534 iStudy = varargin{2};
1535 sStudy = bst_get('Study', iStudy);
1536 isDefaultStudy = strcmpi(sStudy.Name, bst_get('DirDefaultStudy'));
1537 isGlobalDefault = (iStudy == -3);
1538
1539 % If study is the global default study
1540 sStudies = [];
1541 iStudies = [];
1542 if isGlobalDefault
1543 % Get all the subjects of the protocol
1544 nbSubjects = bst_get('SubjectCount');
1545 for iSubject = 1:nbSubjects
1546 sSubject = bst_get('Subject', iSubject, 1);
1547 if sSubject.UseDefaultChannel
1548 [tmp_sStudies, tmp_iStudies] = bst_get('StudyWithSubject', sSubject.FileName);
1549 sStudies = [sStudies, tmp_sStudies];
1550 iStudies = [iStudies, tmp_iStudies];
1551 end
1552 end
1553 % Else, if study is a subject's default study (ie. channel file is shared by all studies of one subject)
1554 elseif isDefaultStudy
1555 % Get all the subject's studies
1556 [sStudies, iStudies] = bst_get('StudyWithSubject', sStudy.BrainStormSubject, 'intra_subject', 'default_study');
1557 else
1558 % Normal: one channel per condition
1559 sStudies = sStudy;
1560 iStudies = iStudy;
1561 end
1562 % Get all the DataFiles for all these studies
1563 for i = 1:length(sStudies)
1564 nData = length(sStudies(i).Data);
1565 argout1 = [argout1, repmat(iStudies(i), [1,nData])];
1566 argout2 = [argout2, 1:nData];
1567 end
1568
1569
1570 %% ==== DATA FOR STUDIES (INCLUDING SHARED STUDIES) ====
1571 % Usage: [iStudies, iDatas] = bst_get('DataForStudies', iStudies)
1572 case 'DataForStudies'
1573 iStudies = varargin{2};
1574 for i = 1:length(iStudies)
1575 [tmp_iStudies, tmp_iDatas] = bst_get('DataForStudy', iStudies(i));
1576 argout1 = [argout1, tmp_iStudies];
1577 argout2 = [argout2, tmp_iDatas];
1578 end
1579
1580 %% ==== DATA FILE FOR CHANNEL FILE ====
1581 % Usage: DataFiles = bst_get('DataForChannelFile', ChannelFile)
1582 case 'DataForChannelFile'
1583 ChannelFile = varargin{2};
1584 DataFiles = {};
1585 % Get study for the given channel file
1586 [sStudy, iStudy] = bst_get('ChannelFile', ChannelFile);
1587 if isempty(sStudy)
1588 return;
1589 end
1590 % Get dependent data files
1591 [iStudies, iDatas] = bst_get('DataForStudy', iStudy);
1592 % Get all the Data filenames
1593 for i = 1:length(iStudies)
1594 sStudy = bst_get('Study', iStudies(i));
1595 DataFiles = cat(2, DataFiles, {sStudy.Data(iDatas(i)).FileName});
1596 end
1597 argout1 = DataFiles;
1598
1599
1600 %% ==== RESULTS FILE ====
1601 % Usage: [sStudy, iStudy, iResult] = bst_get('ResultsFile', ResultsFile, iStudies)
1602 % [sStudy, iStudy, iResult] = bst_get('ResultsFile', ResultsFile)
1603 case 'ResultsFile'
1604 % No protocol in database
1605 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1606 return;
1607 end
1608 % Input #2: ResultsFile
1609 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1610 ResultsFile = varargin{2};
1611 ResultsFile = strrep(ResultsFile, ProtocolInfo.STUDIES, '');
1612 % Input #3: iStudies
1613 if (nargin < 3)
1614 iStudies = [];
1615 else
1616 iStudies = varargin{3};
1617 end
1618 % Look for surface file in all the surfaces of all subjects
1619 [argout1, argout2, argout3] = findFileInStudies('Result', 'FileName', ResultsFile, iStudies);
1620
1621
1622 %% ==== RESULTS FOR DATA FILE ====
1623 % Usage: [sStudy, iStudy, iResults] = bst_get('ResultsForDataFile', DataFile) : search the whole protocol
1624 % Usage: [sStudy, iStudy, iResults] = bst_get('ResultsForDataFile', DataFile, iStudies) : search only the specified studies
1625 case 'ResultsForDataFile'
1626 % No protocol in database
1627 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1628 return;
1629 end
1630 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1631 % Input #2: DataFile
1632 DataFile = varargin{2};
1633 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1634 % Determine in which studies to search for ResultsFile
1635 if (nargin >= 3)
1636 % Studies specified in argument
1637 iStudy = varargin{3};
1638 else
1639 % Get study in which DataFile is located
1640 [sStudy, iStudy] = bst_get('DataFile', DataFile);
1641 if isempty(iStudy)
1642 return;
1643 end
1644 end
1645 % Search selected studies
1646 [argout1, argout2, argout3] = findFileInStudies('Result', 'DataFile', DataFile, iStudy);
1647
1648
1649 %% ==== STAT FILE ====
1650 % Usage: [sStudy, iStudy, iData] = bst_get('StatFile', StatFile, iStudies)
1651 % [sStudy, iStudy, iData] = bst_get('StatFile', StatFile)
1652 case 'StatFile'
1653 % No protocol in database
1654 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1655 return;
1656 end
1657 % Input #2: SataFile
1658 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1659 StatFile = varargin{2};
1660 StatFile = strrep(StatFile, ProtocolInfo.STUDIES, '');
1661 % Input #3: iStudies
1662 if (nargin < 3)
1663 iStudies = [];
1664 else
1665 iStudies = varargin{3};
1666 end
1667 % Look for surface file in all the surfaces of all subjects
1668 [argout1, argout2, argout3] = findFileInStudies('Stat', 'FileName', StatFile, iStudies);
1669
1670
1671 %% ==== STAT FOR DATA FILE ====
1672 % Usage: [sStudy, iStudy, iResults] = bst_get('StatForDataFile', DataFile) : search the whole protocol
1673 % Usage: [sStudy, iStudy, iResults] = bst_get('StatForDataFile', DataFile, iStudies) : search only the specified studies
1674 case 'StatForDataFile'
1675 % No protocol in database
1676 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1677 return;
1678 end
1679 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1680 % Parse inputs
1681 if (nargin >= 2)
1682 DataFile = varargin{2};
1683 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1684 else
1685 error('Invalid call to bst_get().');
1686 end
1687 % Determine in which studies to search for ResultsFile
1688 if (nargin >= 3)
1689 % Studies specified in argument
1690 iStudies = varargin{3};
1691 else
1692 % Get study in which DataFile is located
1693 [sStudies, iStudies] = bst_get('DataFile', DataFile);
1694 if isempty(iStudies)
1695 return;
1696 end
1697 end
1698 % Search selected studies
1699 [argout1, argout2, argout3] = findFileInStudies('Stat', 'DataFile', DataFile, iStudies);
1700
1701 %% ==== TIMEFREQ FILE ====
1702 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqFile', TimefreqFile, iStudies)
1703 % [sStudy, iStudy, iTimefreq] = bst_get('TimefreqFile', TimefreqFile)
1704 case 'TimefreqFile'
1705 % No protocol in database
1706 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1707 return;
1708 end
1709 % Input #2: TimefreqFile
1710 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1711 TimefreqFile = varargin{2};
1712 TimefreqFile = strrep(TimefreqFile, ProtocolInfo.STUDIES, '');
1713 % Remove optional RefRowName
1714 iPipe = find(TimefreqFile == '|', 1);
1715 if ~isempty(iPipe)
1716 TimefreqFile = TimefreqFile(1:iPipe-1);
1717 end
1718 % Input #3: iStudies
1719 if (nargin < 3)
1720 iStudies = [];
1721 else
1722 iStudies = varargin{3};
1723 end
1724 % Look for surface file in all the surfaces of all subjects
1725 [argout1, argout2, argout3] = findFileInStudies('Timefreq', 'FileName', TimefreqFile, iStudies);
1726
1727 %% ==== TIMEFREQ FOR FILE ====
1728 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForFile', FileName, iStudies) : search only the specified studies
1729 % [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForFile', FileName) : search the whole protocol
1730 case 'TimefreqForFile'
1731 % No protocol in database
1732 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1733 return;
1734 end
1735 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1736 % Parse inputs
1737 if (nargin >= 2)
1738 FileName = varargin{2};
1739 FileName = strrep(FileName, ProtocolInfo.STUDIES, '');
1740 else
1741 error('Invalid call to bst_get().');
1742 end
1743 % Get study in which file is located
1744 if (nargin >= 3)
1745 iStudies = varargin{3};
1746 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName, iStudies);
1747 else
1748 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName);
1749 end
1750 % If file was not found
1751 if isempty(iStudy)
1752 return;
1753 end
1754 % Search direct dependent files
1755 [tmp, tmp, iTf] = findFileInStudies('Timefreq', 'DataFile', FileName, iStudy);
1756 % Data files: get all the depending results, and then all the timefreq for those results
1757 if strcmpi(DataType, 'data')
1758 [tmp, tmp, iResults] = bst_get('ResultsForDataFile', FileName, iStudy);
1759 for i = 1:length(iResults);
1760 % Search selected studies
1761 [tmp, tmp, iTfRes] = findFileInStudies('Timefreq', 'DataFile', sStudy.Result(iResults(i)).FileName, iStudy);
1762 if ~isempty(iTfRes)
1763 iTf = [iTf iTfRes];
1764 end
1765 end
1766 end
1767 % Return results
1768 if ~isempty(iTf)
1769 argout1 = sStudy;
1770 argout2 = iStudy;
1771 argout3 = iTf;
1772 end
1773
1774
1775 %% ==== DIPOLES FOR FILE ====
1776 % Usage: [sStudy, iStudy, iDipoles] = bst_get('DipolesForFile', FileName, iStudies) : search only the specified studies
1777 % [sStudy, iStudy, iDipoles] = bst_get('DipolesForFile', FileName) : search the whole protocol
1778 case 'DipolesForFile'
1779 % No protocol in database
1780 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1781 return;
1782 end
1783 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1784 % Parse inputs
1785 if (nargin >= 2)
1786 FileName = varargin{2};
1787 FileName = strrep(FileName, ProtocolInfo.STUDIES, '');
1788 else
1789 error('Invalid call to bst_get().');
1790 end
1791 % Get study in which file is located
1792 if (nargin >= 3)
1793 iStudies = varargin{3};
1794 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName, iStudies);
1795 else
1796 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName);
1797 end
1798 % If file was not found
1799 if isempty(iStudy)
1800 return;
1801 end
1802 % Search direct dependent files
1803 [tmp, tmp, iDip] = findFileInStudies('Dipoles', 'DataFile', FileName, iStudy);
1804 % Data files: get all the depending results, and then all the timefreq for those results
1805 if strcmpi(DataType, 'data')
1806 [tmp, tmp, iResults] = bst_get('ResultsForDataFile', FileName, iStudy);
1807 for i = 1:length(iResults);
1808 % Search selected studies
1809 [tmp, tmp, iDipRes] = findFileInStudies('Dipoles', 'DataFile', sStudy.Result(iResults(i)).FileName, iStudy);
1810 if ~isempty(iDipRes)
1811 iDip = [iDip, iDipRes];
1812 end
1813 end
1814 end
1815 % Return results
1816 if ~isempty(iDip)
1817 argout1 = sStudy;
1818 argout2 = iStudy;
1819 argout3 = iDip;
1820 end
1821
1822
1823 %% ==== TIMEFREQ FOR KERNEL ====
1824 % Find all the timefreq files dependent from links due to a given kernel
1825 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForKernel', KernelFile)
1826 case 'TimefreqForKernel'
1827 sFoundStudy = [];
1828 iFoundStudy = [];
1829 iFoundTimefreq = [];
1830 % No protocol in database
1831 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1832 return;
1833 end
1834 % Get study in which file is located
1835 KernelFile = varargin{2};
1836 [sStudy, iStudy, iFile, DataType] = bst_get('ResultsFile', KernelFile);
1837 if isempty(iStudy)
1838 return;
1839 end
1840 % Get all the data files relative with this kernel
1841 [iDepStudies, iDepDatas] = bst_get('DataForStudy', iStudy);
1842 % Keep only once each study
1843 iDepStudies = unique(iDepStudies);
1844 % Process all the dependent studies
1845 for iSt = 1:length(iDepStudies)
1846 % Get the study structure
1847 sDepStudy = bst_get('Study', iDepStudies(iSt));
1848 % Process each timefreq file separately
1849 for iTf = 1:length(sDepStudy.Timefreq)
1850 DataFile = sDepStudy.Timefreq(iTf).DataFile;
1851 % Keep only the files that are linked to LINKS
1852 if isempty(DataFile) || (length(DataFile) < 5) || ~isequal(DataFile(1:5), 'link|')
1853 continue;
1854 end
1855 % Split link
1856 splitFile = str_split(DataFile, '|');
1857 % If the kernel is found: add it to the found list
1858 if file_compare(splitFile{2}, KernelFile)
1859 sFoundStudy = [sFoundStudy sDepStudy];
1860 iFoundStudy = [iFoundStudy, iDepStudies(iSt)];
1861 iFoundTimefreq = [iFoundTimefreq, iTf];
1862 end
1863 end
1864 end
1865 % Return findings
1866 argout1 = sFoundStudy;
1867 argout2 = iFoundStudy;
1868 argout3 = iFoundTimefreq;
1869
1870
1871 %% ==== DIPOLES FOR KERNEL ====
1872 % Find all the dipoles files dependent from links due to a given kernel
1873 % Usage: [sStudy, iStudy, iDipoles] = bst_get('TimefreqForKernel', KernelFile)
1874 case 'DipolesForKernel'
1875 sFoundStudy = [];
1876 iFoundStudy = [];
1877 iFoundDipoles = [];
1878 % No protocol in database
1879 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1880 return;
1881 end
1882 % Get study in which file is located
1883 KernelFile = varargin{2};
1884 [sStudy, iStudy, iFile, DataType] = bst_get('ResultsFile', KernelFile);
1885 if isempty(iStudy)
1886 return;
1887 end
1888 % Get all the data files relative with this kernel
1889 [iDepStudies, iDepDatas] = bst_get('DataForStudy', iStudy);
1890 % Keep only once each study
1891 iDepStudies = unique(iDepStudies);
1892 % Process all the dependent studies
1893 for iSt = 1:length(iDepStudies)
1894 % Get the study structure
1895 sDepStudy = bst_get('Study', iDepStudies(iSt));
1896 % Process each timefreq file separately
1897 for iDip = 1:length(sDepStudy.Dipoles)
1898 DataFile = sDepStudy.Dipoles(iDip).DataFile;
1899 % Keep only the files that are linked to LINKS
1900 if isempty(DataFile) || (length(DataFile) < 5) || ~isequal(DataFile(1:5), 'link|')
1901 continue;
1902 end
1903 % Split link
1904 splitFile = str_split(DataFile, '|');
1905 % If the kernel is found: add it to the found list
1906 if file_compare(splitFile{2}, KernelFile)
1907 sFoundStudy = [sFoundStudy sDepStudy];
1908 iFoundStudy = [iFoundStudy, iDepStudies(iSt)];
1909 iFoundDipoles = [iFoundDipoles, iDip];
1910 end
1911 end
1912 end
1913 % Return findings
1914 argout1 = sFoundStudy;
1915 argout2 = iFoundStudy;
1916 argout3 = iFoundDipoles;
1917
1918
1919 %% ==== DIPOLES FILE ====
1920 % Usage: [sStudy, iStudy, iDipole] = bst_get('DipolesFile', DipolesFile, iStudies)
1921 % [sStudy, iStudy, iDipole] = bst_get('DipolesFile', DipolesFile)
1922 case 'DipolesFile'
1923 % No protocol in database
1924 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1925 return;
1926 end
1927 % Input #2: DipolesFile
1928 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1929 DipolesFile = varargin{2};
1930 DipolesFile = strrep(DipolesFile, ProtocolInfo.STUDIES, '');
1931 % Input #3: iStudies
1932 if (nargin < 3)
1933 iStudies = [];
1934 else
1935 iStudies = varargin{3};
1936 end
1937 % Look for surface file in all the surfaces of all subjects
1938 [argout1, argout2, argout3] = findFileInStudies('Dipoles', 'FileName', DipolesFile, iStudies);
1939
1940
1941 %% ==== MATRIX FILE ====
1942 % Usage: [sStudy, iStudy, iDipole] = bst_get('MatrixFile', MatrixFile, iStudies)
1943 % [sStudy, iStudy, iDipole] = bst_get('MatrixFile', MatrixFile)
1944 case 'MatrixFile'
1945 % No protocol in database
1946 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1947 return;
1948 end
1949 % Input #2: MatrixFile
1950 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1951 MatrixFile = varargin{2};
1952 MatrixFile = strrep(MatrixFile, ProtocolInfo.STUDIES, '');
1953 % Input #3: iStudies
1954 if (nargin < 3)
1955 iStudies = [];
1956 else
1957 iStudies = varargin{3};
1958 end
1959 % Look for surface file in all the surfaces of all subjects
1960 [argout1, argout2, argout3] = findFileInStudies('Matrix', 'FileName', MatrixFile, iStudies);
1961
1962 %% ==== IMAGE FILE ====
1963 % Usage: [sStudy, iStudy, iDipole] = bst_get('ImageFile', ImageFile, iStudies)
1964 % [sStudy, iStudy, iDipole] = bst_get('ImageFile', ImageFile)
1965 case 'ImageFile'
1966 % No protocol in database
1967 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1968 return;
1969 end
1970 % Input #2: ImageFile
1971 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1972 ImageFile = varargin{2};
1973 ImageFile = strrep(ImageFile, ProtocolInfo.STUDIES, '');
1974 % Input #3: iStudies
1975 if (nargin < 3)
1976 iStudies = [];
1977 else
1978 iStudies = varargin{3};
1979 end
1980 % Look for surface file in all the surfaces of all subjects
1981 [argout1, argout2, argout3] = findFileInStudies('Image', 'FileName', ImageFile, iStudies);
1982
1983
1984 %% ==== ANY FILE ====
1985 % Usage: [sStudy, iStudy, iFile, DataType, sItem] = bst_get('AnyFile', FileName, iStudies)
1986 % [sStudy, iStudy, iFile, DataType, sItem] = bst_get('AnyFile', FileName)
1987 case 'AnyFile'
1988 % Input #2: FileName
1989 FileName = varargin{2};
1990 if isempty(FileName)
1991 return
1992 end
1993 % Input #3: iStudies
1994 if (nargin < 3)
1995 iStudies = [];
1996 else
1997 iStudies = varargin{3};
1998 end
1999 % Get data format
2000 fileType = file_gettype(FileName);
2001 if isempty(fileType)
2002 error('File type is not recognized.');
2003 end
2004 sItem = [];
2005 % Get information related with this file
2006 switch (fileType)
2007 % ===== FUNCTIONAL =====
2008 case 'channel'
2009 [sStudy, iStudy] = bst_get('ChannelFile', FileName);
2010 iItem = 1;
2011 if (nargout >= 5) && ~isempty(sStudy)
2012 sItem = sStudy.Channel;
2013 end
2014 case 'headmodel'
2015 [sStudy, iStudy, iItem] = bst_get('HeadModelFile', FileName);
2016 if (nargout >= 5) && ~isempty(sStudy)
2017 sItem = sStudy.HeadModel(iItem);
2018 end
2019 case 'noisecov'
2020 [sStudy, iStudy, iItem] = bst_get('NoiseCovFile', FileName);
2021 if (nargout >= 5) && ~isempty(sStudy)
2022 sItem = sStudy.NoiseCov(iItem);
2023 end
2024 case 'ndatacov'
2025 [sStudy, iStudy, iItem] = bst_get('DataCovFile', FileName);
2026 if (nargout >= 5) && ~isempty(sStudy)
2027 sItem = sStudy.NoiseCov(iItem);
2028 end
2029 case 'data'
2030 [sStudy, iStudy, iItem] = bst_get('DataFile', FileName, iStudies);
2031 if (nargout >= 5) && ~isempty(sStudy)
2032 sItem = sStudy.Data(iItem);
2033 end
2034 case {'results', 'link'}
2035 [sStudy, iStudy, iItem] = bst_get('ResultsFile', FileName, iStudies);
2036 if (nargout >= 5) && ~isempty(sStudy)
2037 sItem = sStudy.Result(iItem);
2038 end
2039 case {'presults', 'pdata','ptimefreq','pmatrix'}
2040 [sStudy, iStudy, iItem] = bst_get('StatFile', FileName, iStudies);
2041 if (nargout >= 5) && ~isempty(sStudy)
2042 sItem = sStudy.Stat(iItem);
2043 end
2044 case 'dipoles'
2045 [sStudy, iStudy, iItem] = bst_get('DipolesFile', FileName, iStudies);
2046 if (nargout >= 5) && ~isempty(sStudy)
2047 sItem = sStudy.Dipoles(iItem);
2048 end
2049 case 'timefreq'
2050 % Remove optional RefRowName
2051 iPipe = find(FileName == '|', 1);
2052 if ~isempty(iPipe)
2053 FileName = FileName(1:iPipe-1);
2054 end
2055 [sStudy, iStudy, iItem] = bst_get('TimefreqFile', FileName, iStudies);
2056 if (nargout >= 5) && ~isempty(sStudy)
2057 sItem = sStudy.Timefreq(iItem);
2058 end
2059 case 'matrix'
2060 [sStudy, iStudy, iItem] = bst_get('MatrixFile', FileName, iStudies);
2061 if (nargout >= 5) && ~isempty(sStudy)
2062 sItem = sStudy.Matrix(iItem);
2063 end
2064 case 'brainstormstudy'
2065 [sStudy, iStudy] = bst_get('Study', FileName);
2066 iItem = 0;
2067 if (nargout >= 5) && ~isempty(sStudy)
2068 sItem = sStudy;
2069 end
2070 case {'image', 'video', 'videolink'}
2071 [sStudy, iStudy, iItem] = bst_get('ImageFile', FileName, iStudies);
2072 if (nargout >= 5) && ~isempty(sStudy)
2073 sItem = sStudy.Image(iItem);
2074 end
2075 % ===== ANATOMY =====
2076 case {'cortex','scalp','innerskull','outerskull','tess','fibers','fem'}
2077 [sStudy, iStudy, iItem] = bst_get('SurfaceFile', FileName);
2078 if (nargout >= 5) && ~isempty(sStudy)
2079 sItem = sStudy.Surface(iItem);
2080 end
2081 case 'subjectimage'
2082 [sStudy, iStudy, iItem] = bst_get('MriFile', FileName);
2083 if (nargout >= 5) && ~isempty(sStudy)
2084 sItem = sStudy.Anatomy(iItem);
2085 end
2086 case 'brainstormsubject'
2087 [sStudy, iStudy] = bst_get('Subject', FileName);
2088 iItem = 0;
2089 if (nargout >= 5) && ~isempty(sStudy)
2090 sItem = sStudy;
2091 end
2092 otherwise
2093 error('File type is not recognized.');
2094 end
2095 argout1 = sStudy;
2096 argout2 = iStudy;
2097 argout3 = iItem;
2098 argout4 = fileType;
2099 if (nargout >= 5)
2100 argout5 = sItem;
2101 end
2102
2103
2104 %% ==== GET RELATED DATA FILE ====
2105 % Usage: DataFile = bst_get('RelatedDataFile', FileName, iStudies)
2106 % DataFile = bst_get('RelatedDataFile', FileName)
2107 case 'RelatedDataFile'
2108 % Input #2: FileName
2109 FileName = varargin{2};
2110 % Input #3: iStudies
2111 if (nargin < 3)
2112 iStudies = [];
2113 else
2114 iStudies = varargin{3};
2115 end
2116 % Get file in database
2117 [sStudy, iStudy, iFile, fileType] = bst_get('AnyFile', FileName, iStudies);
2118 % If this data file does not belong to any study
2119 if isempty(sStudy)
2120 return;
2121 end
2122 % Get associated data file
2123 switch (fileType)
2124 case 'data'
2125 RelatedDataFile = sStudy.Data(iFile).FileName;
2126 case {'pdata','presults','ptimefreq','pmatrix'}
2127 RelatedDataFile = sStudy.Stat(iFile).DataFile;
2128 case {'results', 'link'}
2129 RelatedDataFile = sStudy.Result(iFile).DataFile;
2130 case 'dipoles'
2131 RelatedDataFile = sStudy.Dipoles(iFile).DataFile;
2132 case 'timefreq'
2133 RelatedDataFile = sStudy.Timefreq(iFile).DataFile;
2134 otherwise
2135 RelatedDataFile = '';
2136 end
2137 % If related file is results: get related data file
2138 if ~isempty(RelatedDataFile)
2139 relFileType = file_gettype(RelatedDataFile);
2140 if ismember(relFileType, {'link','results'})
2141 RelatedDataFile = bst_get('RelatedDataFile', RelatedDataFile, iStudy);
2142 end
2143 end
2144 % Return file
2145 argout1 = RelatedDataFile;
2146
2147 %% ==== ALL CONDITIONS FOR ONE SUBJECT ====
2148 % Usage: [Conditions] = bst_get('ConditionsForSubject', SubjectFile)
2149 case 'ConditionsForSubject'
2150 % Parse inputs
2151 if (nargin == 2)
2152 SubjectFile = varargin{2};
2153 else
2154 error('Invalid call to bst_get().');
2155 end
2156 % Get list of studies associated with subject
2157 sStudies = bst_get('StudyWithSubject', SubjectFile);
2158 % Get Conditions for each study
2159 Conditions = {};
2160 for i = 1:length(sStudies)
2161 % Test if the condition of this study was not added previously
2162 isNewCondition = 1;
2163 for iCond = 1:length(Conditions)
2164 % If new condition is found
2165 % (and excludes DirAnalysisIntra and DirDefaultSubject from list)
2166 if isempty(sStudies(i).Condition) || ...
2167 isequal(sStudies(i).Condition, Conditions(iCond)) || ...
2168 strcmpi(sStudies(i).Condition{1}, bst_get('DirAnalysisIntra')) || ...
2169 strcmpi(sStudies(i).Condition{1}, bst_get('DirDefaultSubject'))
2170 isNewCondition = 0;
2171 break;
2172 end
2173 end
2174 % If Condition is not added yet : add it to the list
2175 if isNewCondition && ~isempty(sStudies(i).Condition)
2176 Conditions{end+1} = sStudies(i).Condition{1};
2177 end
2178 end
2179 % Return conditions list
2180 argout1 = Conditions;
2181
2182
2183 %% ==== ANATOMY DEFAULTS ====
2184 % Returns the list of all the anatomy defaults (distributed with the software + user defined)
2185 case 'AnatomyDefaults'
2186 % Parse inputs
2187 if (nargin == 2)
2188 AnatName = varargin{2};
2189 else
2190 AnatName = [];
2191 end
2192 % Get templates from the brainstorm3 folder
2193 progDir = bst_fullfile(bst_get('BrainstormDefaultsDir'), 'anatomy');
2194 progFiles = dir(progDir);
2195 % Get templates from the user folder
2196 userDir = bst_fullfile(bst_get('UserDefaultsDir'), 'anatomy');
2197 userFiles = dir(userDir);
2198 % Combine the two lists
2199 AllFiles = cat(2, cellfun(@(c)bst_fullfile(progDir,c), {progFiles.name}, 'UniformOutput', 0), ...
2200 cellfun(@(c)bst_fullfile(userDir,c), setdiff({userFiles.name}, {progFiles.name}), 'UniformOutput', 0));
2201 % Initialize list of defaults
2202 sTemplates = repmat(struct('FilePath',[],'Name',[]), 0);
2203 % Find all the valid defaults (.zip files or subdirectory with a brainstormsubject.mat in it)
2204 for i = 1:length(AllFiles)
2205 % Decompose file name
2206 [fPath, fBase, fExt] = bst_fileparts(AllFiles{i});
2207 % Entry is a directory W/ a name that does not start with a '.'
2208 if isempty(fBase) || strcmpi(fBase(1),'.') || (~isempty(fExt) && ~strcmpi(fExt, '.zip'))
2209 continue;
2210 end
2211 % If it's a folder: check for a brainstormsubject file
2212 if isdir(AllFiles{i})
2213 bstFiles = dir(bst_fullfile(AllFiles{i}, 'brainstormsubject*.mat'));
2214 if (length(bstFiles) == 1)
2215 sTemplates(end+1).FilePath = AllFiles{i};
2216 sTemplates(end).Name = fBase;
2217 end
2218 % If it's a zip file
2219 elseif isequal(fExt, '.zip')
2220 sTemplates(end+1).FilePath = AllFiles{i};
2221 sTemplates(end).Name = fBase;
2222 end
2223 end
2224 % Get defaults from internet
2225 if ~ismember('icbm152', lower({sTemplates.Name}))
2226 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_2019';
2227 sTemplates(end).Name = 'ICBM152';
2228 end
2229 if ~ismember('icbm152_2019', lower({sTemplates.Name}))
2230 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_2019';
2231 sTemplates(end).Name = 'ICBM152_2019';
2232 end
2233 if ~ismember('icbm152_brainsuite_2016', lower({sTemplates.Name}))
2234 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_BrainSuite_2016';
2235 sTemplates(end).Name = 'ICBM152_BrainSuite_2016';
2236 end
2237 if ~ismember('colin27_2016', lower({sTemplates.Name}))
2238 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Colin27_2016';
2239 sTemplates(end).Name = 'Colin27_2016';
2240 end
2241 if ~ismember('colin27_brainsuite_2016', lower({sTemplates.Name}))
2242 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Colin27_BrainSuite_2016';
2243 sTemplates(end).Name = 'Colin27_BrainSuite_2016';
2244 end
2245 if ~ismember('bci-dni_brainsuite_2020', lower({sTemplates.Name}))
2246 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=BCI-DNI_BrainSuite_2020';
2247 sTemplates(end).Name = 'BCI-DNI_BrainSuite_2020';
2248 end
2249 if ~ismember('uscbrain_brainsuite_2020', lower({sTemplates.Name}))
2250 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=USCBrain_BrainSuite_2020';
2251 sTemplates(end).Name = 'USCBrain_BrainSuite_2020';
2252 end
2253 if ~ismember('fsaverage_2020', lower({sTemplates.Name}))
2254 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=FSAverage_2020';
2255 sTemplates(end).Name = 'FsAverage_2020';
2256 end
2257 if ~ismember('kabdebon_7w', lower({sTemplates.Name}))
2258 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Kabdebon_7w';
2259 sTemplates(end).Name = 'Kabdebon_7w';
2260 end
2261 if ~ismember('oreilly_0.5m', lower({sTemplates.Name}))
2262 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_0.5m';
2263 sTemplates(end).Name = 'Oreilly_0.5m';
2264 end
2265 if ~ismember('oreilly_1m', lower({sTemplates.Name}))
2266 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_1m';
2267 sTemplates(end).Name = 'Oreilly_1m';
2268 end
2269 if ~ismember('oreilly_2m', lower({sTemplates.Name}))
2270 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_2m';
2271 sTemplates(end).Name = 'Oreilly_2m';
2272 end
2273 if ~ismember(lower({sTemplates.Name}), 'oreilly_3m')
2274 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_3m';
2275 sTemplates(end).Name = 'Oreilly_3m';
2276 end
2277 if ~ismember('oreilly_4.5m', lower({sTemplates.Name}))
2278 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_4.5m';
2279 sTemplates(end).Name = 'Oreilly_4.5m';
2280 end
2281 if ~ismember('oreilly_6m', lower({sTemplates.Name}))
2282 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_6m';
2283 sTemplates(end).Name = 'Oreilly_6m';
2284 end
2285 if ~ismember('oreilly_7.5m', lower({sTemplates.Name}))
2286 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_7.5m';
2287 sTemplates(end).Name = 'Oreilly_7.5m';
2288 end
2289 if ~ismember('oreilly_9m', lower({sTemplates.Name}))
2290 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_9m';
2291 sTemplates(end).Name = 'Oreilly_9m';
2292 end
2293 if ~ismember('oreilly_10.5m', lower({sTemplates.Name}))
2294 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_10.5m';
2295 sTemplates(end).Name = 'Oreilly_10.5m';
2296 end
2297 if ~ismember('oreilly_12m', lower({sTemplates.Name}))
2298 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_12m';
2299 sTemplates(end).Name = 'Oreilly_12m';
2300 end
2301 if ~ismember('oreilly_15m', lower({sTemplates.Name}))
2302 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_15m';
2303 sTemplates(end).Name = 'Oreilly_15m';
2304 end
2305 if ~ismember('oreilly_18m', lower({sTemplates.Name}))
2306 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_18m';
2307 sTemplates(end).Name = 'Oreilly_18m';
2308 end
2309 if ~ismember('oreilly_24m', lower({sTemplates.Name}))
2310 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_24m';
2311 sTemplates(end).Name = 'Oreilly_24m';
2312 end
2313 % If a specific template was requested
2314 if ~isempty(AnatName)
2315 iAnat = find(strcmpi({sTemplates.Name}, AnatName));
2316 sTemplates = sTemplates(iAnat);
2317 end
2318 % Sort in alphabetical order
2319 if ~isempty(sTemplates)
2320 [tmp__, I] = sort_nat({sTemplates(2:end).Name});
2321 sTemplates = sTemplates([1, I+1]);
2322 end
2323 % Return defaults list
2324 argout1 = sTemplates;
2325
2326
2327 %% ==== MNI ATLASES ====
2328 % Returns the list of all the available MNI atlases
2329 case 'MniAtlasDefaults'
2330 % Get templates from the brainstorm3 folder
2331 mniDir = bst_fullfile(bst_get('UserDefaultsDir'), 'mniatlas');
2332 mniFiles = dir(bst_fullfile(mniDir, '*.nii.gz'));
2333 mniFiles = cellfun(@(c)bst_fullfile(mniDir,c), {mniFiles.name}, 'UniformOutput', 0);
2334 % Initialize list of defaults
2335 sTemplates = repmat(struct('FilePath',[],'Name',[],'Info',[]), 0);
2336 % Find all the valid defaults (.zip files or subdirectory with a brainstormsubject.mat in it)
2337 for i = 1:length(mniFiles)
2338 % Decompose file name
2339 [fPath, fBase, fExt] = bst_fileparts(mniFiles{i});
2340 % Keep only files with .nii and .nii.gz extensions
2341 if ~isempty(fBase) && (fBase(1) ~= '.') && ~isempty(fExt) && strcmpi(fExt, '.gz')
2342 sTemplates(end+1).FilePath = mniFiles{i};
2343 sTemplates(end).Name = strrep(fBase, '.nii', '');
2344 sTemplates(end).Info = '';
2345 end
2346 end
2347 % Sort in alphabetical order
2348 if ~isempty(sTemplates)
2349 [tmp__, I] = sort_nat(lower({sTemplates.Name}));
2350 sTemplates = sTemplates(I);
2351 end
2352
2353 % Get defaults from internet
2354 if ~ismember('aal2', lower({sTemplates.Name}))
2355 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AAL2';
2356 sTemplates(end).Name = 'AAL2';
2357 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aal/';
2358 end
2359 if ~ismember('aal3', lower({sTemplates.Name}))
2360 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AAL3';
2361 sTemplates(end).Name = 'AAL3';
2362 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aal/';
2363 end
2364 if ~ismember('aicha', lower({sTemplates.Name}))
2365 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AICHA';
2366 sTemplates(end).Name = 'AICHA';
2367 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aicha';
2368 end
2369 if ~ismember('brainnetome', lower({sTemplates.Name}))
2370 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brainnetome';
2371 sTemplates(end).Name = 'Brainnetome';
2372 sTemplates(end).Info = 'http://atlas.brainnetome.org/';
2373 end
2374 if ~ismember('brainnetome_leaddbs', lower({sTemplates.Name}))
2375 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brainnetome_leaddbs';
2376 sTemplates(end).Name = 'Brainnetome_leaddbs';
2377 sTemplates(end).Info = 'http://atlas.brainnetome.org/';
2378 end
2379 if ~ismember('brodmann', lower({sTemplates.Name}))
2380 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brodmann';
2381 sTemplates(end).Name = 'Brodmann';
2382 sTemplates(end).Info = 'https://people.cas.sc.edu/rorden/mricro/lesion.html#brod';
2383 end
2384 if ~ismember('hammers83', lower({sTemplates.Name}))
2385 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Hammers';
2386 sTemplates(end).Name = 'Hammers';
2387 sTemplates(end).Info = 'http://brain-development.org/brain-atlases/adult-brain-atlases/';
2388 end
2389 if ~ismember('neuromorphometrics', lower({sTemplates.Name}))
2390 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Neuromorphometrics';
2391 sTemplates(end).Name = 'Neuromorphometrics';
2392 sTemplates(end).Info = 'https://search.kg.ebrains.eu/instances/Dataset/ef48c5e9-6b3c-4d5a-a9a9-e678fe10bdf6';
2393 end
2394 if ~ismember('julich-brain-v25', lower({sTemplates.Name}))
2395 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Julich-Brain-v25';
2396 sTemplates(end).Name = 'Julich-Brain-v25';
2397 sTemplates(end).Info = 'https://search.kg.ebrains.eu/instances/Dataset/ef48c5e9-6b3c-4d5a-a9a9-e678fe10bdf6';
2398 end
2399 if ~ismember('schaefer2018_100_7net', lower({sTemplates.Name}))
2400 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Schaefer2018';
2401 sTemplates(end).Name = 'Schaefer2018';
2402 sTemplates(end).Info = 'https://github.com/ThomasYeoLab/CBIG/tree/master/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal';
2403 end
2404 % Return defaults list
2405 argout1 = sTemplates;
2406
2407
2408 %% ==== EEG DEFAULTS ====
2409 % Returns an array of struct(fullpath, name) of all the Brainstorm eeg nets defaults
2410 % Usage: EegDefaults = bst_get('EegDefaults')
2411 % EegDefaults = bst_get('EegDefaults', TemplateName=[], SetupName=[])
2412 case 'EegDefaults'
2413 % Parse inputs
2414 if (nargin >= 3)
2415 SetupName = varargin{3};
2416 else
2417 SetupName = [];
2418 end
2419 if (nargin >= 2)
2420 TemplateName = varargin{2};
2421 else
2422 TemplateName = [];
2423 end
2424 % Get templates from the brainstorm3 folder
2425 progDir = bst_fullfile(bst_get('BrainstormDefaultsDir'), 'eeg');
2426 progFiles = dir(bst_fullfile(progDir, '*'));
2427 % Get templates from the user folder
2428 userDir = bst_fullfile(bst_get('UserDefaultsDir'), 'eeg');
2429 userFiles = dir(bst_fullfile(userDir, '*'));
2430 % Combine the two lists
2431 dirList = cat(2, cellfun(@(c)bst_fullfile(progDir,c), {progFiles.name}, 'UniformOutput', 0), ...
2432 cellfun(@(c)bst_fullfile(userDir,c), setdiff({userFiles.name}, {progFiles.name}), 'UniformOutput', 0));
2433 % Initialize list of folders
2434 fullDefaultsList = repmat(struct('contents','', 'name',''), 0);
2435 % For each template directory
2436 for iDir = 1:length(dirList)
2437 % Decompose file name
2438 [fPath, fBase, fExt] = bst_fileparts(dirList{iDir});
2439 % Entry is a not a folder, or starts with a "."
2440 if ~isdir(dirList{iDir}) || isempty(fBase) || strcmpi(fBase(1),'.')
2441 continue;
2442 end
2443 % Skip if it is not the requested template
2444 if ~isempty(TemplateName) && ~strcmpi(fBase, TemplateName)
2445 continue;
2446 end
2447 % Get files list
2448 fileList = dir(bst_fullfile(dirList{iDir}, 'channel*.mat'));
2449 defaultsList = repmat(struct('fullpath','', 'name',''), 0);
2450 % Find all the valid defaults (channel files)
2451 for iFile = 1:length(fileList)
2452 [tmp__, baseName] = bst_fileparts(fileList(iFile).name);
2453 baseName = strrep(baseName, 'channel_', '');
2454 baseName = strrep(baseName, '_channel', '');
2455 baseName = strrep(baseName, '_', ' ');
2456 % Skip if it is not the requested template
2457 if ~isempty(SetupName) && ~strcmpi(baseName, SetupName)
2458 continue;
2459 end
2460 % Add to list of templates
2461 iNewDefault = length(defaultsList) + 1;
2462 defaultsList(iNewDefault).fullpath = bst_fullfile(dirList{iDir}, fileList(iFile).name);
2463 defaultsList(iNewDefault).name = baseName;
2464 end
2465 % Add files list to defaults list
2466 if ~isempty(defaultsList)
2467 fullDefaultsList(end + 1) = struct('contents', defaultsList, ...
2468 'name', fBase);
2469 end
2470 end
2471 % Return defaults list
2472 argout1 = fullDefaultsList;
2473
2474
2475 %% ==== GET FILENAMES ====
2476 case 'GetFilenames'
2477 iStudies = varargin{2};
2478 iItems = varargin{3};
2479 DataType = varargin{4};
2480 FileNames = cell(1, length(iStudies));
2481 argout1 = {};
2482 for i = 1:length(iStudies)
2483 % Get study definition
2484 sStudy = bst_get('Study', iStudies(i));
2485 if isempty(sStudy)
2486 continue;
2487 end
2488 % Recordings or sources
2489 switch (DataType)
2490 case 'data'
2491 if (iItems(i) > length(sStudy.Data))
2492 return;
2493 end
2494 FileNames{i} = sStudy.Data(iItems(i)).FileName;
2495 case 'results'
2496 if (iItems(i) > length(sStudy.Result))
2497 return;
2498 end
2499 FileNames{i} = sStudy.Result(iItems(i)).FileName;
2500 case 'timefreq'
2501 if (iItems(i) > length(sStudy.Timefreq))
2502 return;
2503 end
2504 FileNames{i} = sStudy.Timefreq(iItems(i)).FileName;
2505 case 'matrix'
2506 if (iItems(i) > length(sStudy.Matrix))
2507 return;
2508 end
2509 FileNames{i} = sStudy.Matrix(iItems(i)).FileName;
2510 case {'pdata','presults','ptimfreq'}
2511 if (iItems(i) > length(sStudy.Stat))
2512 return;
2513 end
2514 FileNames{i} = sStudy.Stat(iItems(i)).FileName;
2515 end
2516 end
2517 argout1 = FileNames;
2518
2519
2520 %% ==== GUI ====
2521 case 'BstFrame'
2522 if isempty(GlobalData) || isempty(GlobalData.Program.GUI) || isempty(GlobalData.Program.GUI.mainWindow)
2523 argout1 = [];
2524 else
2525 argout1 = GlobalData.Program.GUI.mainWindow.jBstFrame;
2526 end
2527 case 'BstControls'
2528 if isempty(GlobalData) || isempty(GlobalData.Program) || isempty(GlobalData.Program.GUI) || isempty(GlobalData.Program.GUI.mainWindow)
2529 argout1 = [];
2530 else
2531 argout1 = GlobalData.Program.GUI.mainWindow;
2532 end
2533 case 'isGUI'
2534 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'GuiLevel')
2535 argout1 = [];
2536 else
2537 argout1 = (GlobalData.Program.GuiLevel >= 1);
2538 end
2539 case 'GuiLevel'
2540 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'GuiLevel')
2541 argout1 = [];
2542 else
2543 argout1 = GlobalData.Program.GuiLevel;
2544 end
2545 case 'ScreenDef'
2546 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'ScreenDef')
2547 argout1 = [];
2548 else
2549 argout1 = GlobalData.Program.ScreenDef;
2550 end
2551 case 'DecorationSize'
2552 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'DecorationSize')
2553 argout1 = [];
2554 else
2555 argout1 = GlobalData.Program.DecorationSize;
2556 end
2557 case 'Layout'
2558 % Default or current layout structure
2559 if ~isfield(GlobalData, 'Preferences') || ~isfield(GlobalData.Preferences, 'Layout') || ~((nargin == 1) || isfield(GlobalData.Preferences.Layout, varargin{2})) || ~isfield(GlobalData.Preferences.Layout, 'MainWindowPos')
2560 GlobalData.Preferences.Layout = db_template('Layout');
2561 end
2562 % Structure or property call
2563 if (nargin == 2) && ischar(varargin{2}) && isfield(GlobalData.Preferences.Layout, varargin{2})
2564 argout1 = GlobalData.Preferences.Layout.(varargin{2});
2565 elseif (nargin == 1)
2566 argout1 = GlobalData.Preferences.Layout;
2567 else
2568 error('Invalid call to bst_get.');
2569 end
2570
2571 case 'ByteOrder'
2572 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ByteOrder')
2573 argout1 = GlobalData.Preferences.ByteOrder;
2574 else
2575 argout1 = 'l';
2576 end
2577
2578 case 'UniformizeTimeSeriesScales'
2579 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'UniformizeTimeSeriesScales')
2580 argout1 = GlobalData.Preferences.UniformizeTimeSeriesScales;
2581 else
2582 argout1 = 1;
2583 end
2584
2585 case 'FlipYAxis'
2586 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'FlipYAxis')
2587 argout1 = GlobalData.Preferences.FlipYAxis;
2588 else
2589 argout1 = 0;
2590 end
2591
2592 case 'AutoScaleY'
2593 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'AutoScaleY')
2594 argout1 = GlobalData.Preferences.AutoScaleY;
2595 else
2596 argout1 = 1;
2597 end
2598
2599 case 'ShowXGrid'
2600 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowXGrid')
2601 argout1 = GlobalData.Preferences.ShowXGrid;
2602 else
2603 argout1 = 0;
2604 end
2605
2606 case 'ShowYGrid'
2607 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowYGrid')
2608 argout1 = GlobalData.Preferences.ShowYGrid;
2609 else
2610 argout1 = 0;
2611 end
2612
2613 case 'ShowZeroLines'
2614 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowZeroLines')
2615 argout1 = GlobalData.Preferences.ShowZeroLines;
2616 else
2617 argout1 = 1;
2618 end
2619
2620 case 'Resolution'
2621 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'Resolution')
2622 argout1 = GlobalData.Preferences.Resolution;
2623 else
2624 argout1 = [0 0];
2625 end
2626
2627 case 'FixedScaleY'
2628 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'FixedScaleY') && isfield(GlobalData.Preferences.FixedScaleY, varargin{2}) && ~isempty(GlobalData.Preferences.FixedScaleY.(varargin{2}))
2629 argout1 = GlobalData.Preferences.FixedScaleY.(varargin{2});
2630 else
2631 argout1 = [];
2632 end
2633
2634 case 'XScale'
2635 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'XScale')
2636 argout1 = GlobalData.Preferences.XScale;
2637 else
2638 argout1 = 'linear';
2639 end
2640
2641 case 'YScale'
2642 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'YScale')
2643 argout1 = GlobalData.Preferences.YScale;
2644 else
2645 argout1 = 'linear';
2646 end
2647
2648 case 'ShowEventsMode'
2649 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowEventsMode')
2650 argout1 = GlobalData.Preferences.ShowEventsMode;
2651 else
2652 argout1 = 'dot';
2653 end
2654
2655 case 'AutoUpdates'
2656 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'AutoUpdates')
2657 argout1 = GlobalData.Preferences.AutoUpdates;
2658 else
2659 argout1 = 1;
2660 end
2661
2662 case 'ForceMatCompression'
2663 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ForceMatCompression')
2664 argout1 = GlobalData.Preferences.ForceMatCompression;
2665 else
2666 argout1 = 0;
2667 end
2668
2669 case 'IgnoreMemoryWarnings'
2670 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'IgnoreMemoryWarnings')
2671 argout1 = GlobalData.Preferences.IgnoreMemoryWarnings;
2672 else
2673 argout1 = 0;
2674 end
2675
2676 case 'SystemCopy'
2677 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'SystemCopy')
2678 argout1 = GlobalData.Preferences.SystemCopy;
2679 else
2680 argout1 = 0;
2681 end
2682
2683 case 'ExpertMode'
2684 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ExpertMode')
2685 argout1 = GlobalData.Preferences.ExpertMode;
2686 else
2687 argout1 = 0;
2688 end
2689
2690 case 'DisplayGFP'
2691 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DisplayGFP')
2692 argout1 = GlobalData.Preferences.DisplayGFP;
2693 else
2694 argout1 = 1;
2695 end
2696
2697 case 'DownsampleTimeSeries'
2698 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DownsampleTimeSeries')
2699 if (GlobalData.Preferences.DownsampleTimeSeries == 1)
2700 GlobalData.Preferences.DownsampleTimeSeries = 5;
2701 end
2702 argout1 = GlobalData.Preferences.DownsampleTimeSeries;
2703 else
2704 argout1 = 5;
2705 end
2706
2707 case 'GraphicsSmoothing'
2708 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'GraphicsSmoothing')
2709 argout1 = GlobalData.Preferences.GraphicsSmoothing;
2710 else
2711 argout1 = 5;
2712 end
2713
2714 case 'DisableOpenGL'
2715 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DisableOpenGL')
2716 argout1 = GlobalData.Preferences.DisableOpenGL;
2717 else
2718 argout1 = 0;
2719 end
2720
2721 case 'InterfaceScaling'
2722 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'InterfaceScaling')
2723 argout1 = GlobalData.Preferences.InterfaceScaling;
2724 else
2725 % Get screen resolution
2726 if isfield(GlobalData, 'Program') && isfield(GlobalData.Program, 'ScreenDef') && isfield(GlobalData.Program.ScreenDef, 'javaPos') && ~isempty(GlobalData.Program.ScreenDef(1).javaPos)
2727 AvailableRes = [100 125 150 200 250 300 400];
2728 iRes = bst_closest(GlobalData.Program.ScreenDef(1).javaPos.width * 100 / 1920, AvailableRes);
2729 argout1 = AvailableRes(iRes);
2730 else
2731 argout1 = 100;
2732 end
2733 end
2734
2735 case 'JOGLVersion'
2736 % If JOGL1 is available
2737 if exist('javax.media.opengl.GLCanvas', 'class')
2738 argout1 = 1;
2739 % If JOGL2 is available
2740 elseif exist('javax.media.opengl.awt.GLCanvas', 'class')
2741 argout1 = 2;
2742 % No JOGL available
2743 else
2744 argout1 = 0;
2745 end
2746
2747 case 'TSDisplayMode'
2748 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'TSDisplayMode')
2749 argout1 = GlobalData.Preferences.TSDisplayMode;
2750 else
2751 argout1 = 'butterfly';
2752 end
2753
2754 case 'PluginCustomPath'
2755 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'PluginCustomPath') && ~isempty(GlobalData.Preferences.PluginCustomPath)
2756 argout1 = GlobalData.Preferences.PluginCustomPath;
2757 else
2758 argout1 = [];
2759 end
2760
2761 case 'BrainSuiteDir'
2762 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BrainSuiteDir') && ~isempty(GlobalData.Preferences.BrainSuiteDir)
2763 if isdir(GlobalData.Preferences.BrainSuiteDir) && file_exist(bst_fullfile(GlobalData.Preferences.BrainSuiteDir, 'bdp'))
2764 argout1 = GlobalData.Preferences.BrainSuiteDir;
2765 else
2766 argout1 = [];
2767 end
2768 else
2769 argout1 = [];
2770 end
2771
2772 case 'SpmTpmAtlas'
2773 % Get template file
2774 tpmUser = bst_fullfile(bst_get('BrainstormUserDir'), 'defaults', 'spm', 'TPM.nii');
2775 if file_exist(tpmUser)
2776 argout1 = tpmUser;
2777 disp(['SPM12 template found: ' tpmUser]);
2778 return;
2779 end
2780 % If it does not exist: check in brainstorm3 folder
2781 tpmDistrib = bst_fullfile(bst_get('BrainstormHomeDir'), 'defaults', 'spm', 'TPM.nii');
2782 if file_exist(tpmDistrib)
2783 argout1 = tpmDistrib;
2784 disp(['SPM12 template found: ' tpmDistrib]);
2785 return;
2786 end
2787 % If it does not exist: check in spm12 folder
2788 PlugSpm = bst_plugin('GetInstalled', 'spm12');
2789 if ~isempty(PlugSpm)
2790 tpmSpm = bst_fullfile(PlugSpm.Path, PlugSpm.SubFolder, 'tpm', 'TPM.nii');
2791 if file_exist(tpmSpm)
2792 argout1 = tpmSpm;
2793 disp(['SPM12 template found: ' tpmSpm]);
2794 return;
2795 end
2796 else
2797 tpmSpm = '';
2798 end
2799 % Not found...
2800 disp('SPM12 template not found in any of the following folders:');
2801 disp([' - ' tpmUser]);
2802 disp([' - ' tpmDistrib]);
2803 if ~isempty(tpmSpm)
2804 disp([' - ' tpmSpm]);
2805 end
2806 % Return the preferred location: .brainstorm/defaults/spm/TPM.nii
2807 argout1 = tpmUser;
2808
2809 case 'PythonExe'
2810 % Get saved value
2811 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'PythonExe') && ~isempty(GlobalData.Preferences.PythonExe)
2812 if file_exist(GlobalData.Preferences.PythonExe)
2813 argout1 = GlobalData.Preferences.PythonExe;
2814 else
2815 disp(['BST> Error: Python executable not found: ' GlobalData.Preferences.PythonExe]);
2816 argout1 = [];
2817 end
2818 else
2819 argout1 = [];
2820 end
2821 % If not defined in Brainstorm, but set in Matlab
2822 if isempty(argout1)
2823 [pyVer, PythonExe] = bst_python_ver();
2824 if ~isempty(PythonExe) && file_exist(PythonExe)
2825 disp(['BST> Found Python executable: ' PythonExe]);
2826 argout1 = PythonExe;
2827 bst_set('PythonExe', PythonExe);
2828 end
2829 end
2830
2831 case 'ElectrodeConfig'
2832 % Get modality
2833 Modality = varargin{2};
2834 if isempty(Modality) || ~ismember(Modality, {'EEG','ECOG','SEEG','ECOG+SEEG'})
2835 disp(['GET> Invalid modality: ' Modality]);
2836 Modality = 'EEG';
2837 end
2838 % Value was saved previously
2839 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ElectrodeConfig') && isfield(GlobalData.Preferences.ElectrodeConfig, Modality) && isfield(GlobalData.Preferences.ElectrodeConfig.(Modality), 'ContactDiameter')
2840 argout1 = GlobalData.Preferences.ElectrodeConfig.(Modality);
2841 % Get default value
2842 else
2843 switch (Modality)
2844 case 'EEG'
2845 ElectrodeConfig.Type = 'eeg';
2846 ElectrodeConfig.ContactDiameter = 0.010;
2847 ElectrodeConfig.ContactLength = 0.002;
2848 ElectrodeConfig.ElecDiameter = [];
2849 ElectrodeConfig.ElecLength = [];
2850 case 'ECOG'
2851 ElectrodeConfig.Type = 'ecog';
2852 ElectrodeConfig.ContactDiameter = 0.004;
2853 ElectrodeConfig.ContactLength = 0.001;
2854 ElectrodeConfig.ElecDiameter = 0.0005;
2855 ElectrodeConfig.ElecLength = [];
2856 case {'SEEG','ECOG+SEEG'}
2857 ElectrodeConfig.Type = 'seeg';
2858 ElectrodeConfig.ContactDiameter = 0.0008;
2859 ElectrodeConfig.ContactLength = 0.002;
2860 ElectrodeConfig.ElecDiameter = 0.0007;
2861 ElectrodeConfig.ElecLength = 0.070;
2862 end
2863 argout1 = ElectrodeConfig;
2864 end
2865
2866 case 'UseSigProcToolbox'
2867 if isempty(GlobalData.Program.HasSigProcToolbox)
2868 % Check if Signal Processing Toolbox is installed
2869 GlobalData.Program.HasSigProcToolbox = exist('fir2', 'file') == 2;
2870 end
2871 % Return user preferences
2872 if ~GlobalData.Program.HasSigProcToolbox
2873 argout1 = 0;
2874 elseif isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'UseSigProcToolbox')
2875 argout1 = GlobalData.Preferences.UseSigProcToolbox;
2876 else
2877 argout1 = 1;
2878 end
2879
2880 case 'CustomColormaps'
2881 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'CustomColormaps') && ~isempty(GlobalData.Preferences.CustomColormaps)
2882 argout1 = GlobalData.Preferences.CustomColormaps;
2883 else
2884 argout1 = repmat(struct('Name', '', 'CMap', []), 0);
2885 end
2886
2887 case 'BFSProperties'
2888 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BFSProperties') && ~isempty(GlobalData.Preferences.BFSProperties)
2889 argout1 = GlobalData.Preferences.BFSProperties;
2890 else
2891 argout1 = [.33 .0042 .33 .88 .93];
2892 end
2893
2894 case 'LastUsedDirs'
2895 defPref = struct(...
2896 'ImportData', '', ...
2897 'ImportChannel', '', ...
2898 'ImportAnat', '', ...
2899 'ImportMontage', '', ...
2900 'ExportChannel', '', ...
2901 'ExportData', '', ...
2902 'ExportAnat', '', ...
2903 'ExportProtocol', '', ...
2904 'ExportImage', '', ...
2905 'ExportScript', '', ...
2906 'ExportMontage', '');
2907 argout1 = FillMissingFields(contextName, defPref);
2908 % Check that all folders are valid
2909 fields = fieldnames(argout1);
2910 for i = 1:length(fields)
2911 if ~ischar(argout1.(fields{i})) || ~file_exist(argout1.(fields{i}))
2912 argout1.(fields{i}) = '';
2913 end
2914 end
2915
2916 case 'DefaultFormats'
2917 defPref = struct(...
2918 'AnatIn', 'FreeSurfer', ...
2919 'ChannelIn', '', ...
2920 'ChannelOut', '', ...
2921 'DataIn', 'CTF', ...
2922 'DataOut', '', ...
2923 'DipolesIn', '', ...
2924 'DipolesOut', '', ...
2925 'ImageOut', '', ...
2926 'EventsIn', '', ...
2927 'EventsOut', '', ...
2928 'MriIn', '', ...
2929 'MriOut', 'Nifti1', ...
2930 'NoiseCovIn', '', ...
2931 'NoiseCovOut', '', ...
2932 'ResultsIn', '', ...
2933 'ResultsOut', '', ...
2934 'SpmOut', '', ...
2935 'SspIn', '', ...
2936 'SspOut', '', ...
2937 'SurfaceIn', '', ...
2938 'SurfaceOut', '', ...
2939 'LabelIn', '', ...
2940 'LabelOut', '', ...
2941 'TimefreqIn', '', ...
2942 'TimefreqOut', '', ...
2943 'MatrixIn', '', ...
2944 'MatrixOut', '', ...
2945 'MontageIn', '', ...
2946 'MontageOut', '', ...
2947 'FibersIn', '');
2948 argout1 = FillMissingFields(contextName, defPref);
2949
2950 case 'OsType'
2951 switch (mexext)
2952 case 'mexglx', argout1 = 'linux32';
2953 case 'mexa64', argout1 = 'linux64';
2954 case 'mexmaci', argout1 = 'mac32';
2955 case 'mexmaci64', argout1 = 'mac64';
2956 case 'mexs64', argout1 = 'sol64';
2957 case 'mexw32', argout1 = 'win32';
2958 case 'mexw64', argout1 = 'win64';
2959 otherwise, error('Unsupported extension.');
2960 end
2961 % CALL: bst_get('OsType', isMatlab=0)
2962 if (nargin >= 2) && isequal(varargin{2}, 0)
2963 if strcmpi(argout1, 'win32') && (~isempty(strfind(java.lang.System.getProperty('java.home'), '(x86)')) || ~isempty(strfind(java.lang.System.getenv('ProgramFiles(x86)'), '(x86)')))
2964 argout1 = 'win64';
2965 end
2966 end
2967
2968 case 'ImportDataOptions'
2969 defPref = db_template('ImportOptions');
2970 argout1 = FillMissingFields(contextName, defPref);
2971
2972 case 'RawViewerOptions'
2973 defPref = struct(...
2974 'PageDuration', 3, ...
2975 'RemoveBaseline', 'all', ...
2976 'UseCtfComp', 1, ...
2977 'Shortcuts', []);
2978 defPref.Shortcuts = {...
2979 '1', 'event1', 'simple', []; ... % Key, event name, event type (simple,extended,page), epoch time
2980 '2', 'event2', 'simple', []; ...
2981 '3', 'event3', 'simple', []; ...
2982 '4', 'event4', 'simple', []; ...
2983 '5', 'event5', 'simple', []; ...
2984 '6', 'event6', 'simple', []; ...
2985 '7', 'event7', 'simple', []; ...
2986 '8', 'event8', 'simple', []; ...
2987 '9', 'event9', 'simple', []};
2988 argout1 = FillMissingFields(contextName, defPref);
2989 % If invalid PageDuration: reset to default
2990 if (argout1.PageDuration <= 0.1)
2991 argout1.PageDuration = defPref.PageDuration;
2992 end
2993 % If old shortcuts: reset to defaults
2994 if any(size(argout1.Shortcuts) ~= size(defPref.Shortcuts))
2995 disp('BST> Warning: Reset keyboard shortcuts to include new options.');
2996 argout1.Shortcuts = defPref.Shortcuts;
2997 bst_set('RawViewerOptions', argout1);
2998 end
2999
3000 case 'MontageOptions'
3001 defPref = struct('Shortcuts', []);
3002 defPref.Shortcuts = {
3003 %'a', []; ... Note: A is reserved for All channels
3004 'b', []; ...
3005 'c', []; ...
3006 'd', []; ...
3007 'e', []; ...
3008 'f', []; ...
3009 'g', []; ...
3010 'h', []; ...
3011 'i', []; ...
3012 'j', []; ...
3013 'k', []; ...
3014 'l', []; ...
3015 'm', []; ...
3016 'n', []; ...
3017 'o', []; ...
3018 'p', []; ...
3019 'q', []; ...
3020 'r', []; ...
3021 's', []; ...
3022 't', []; ...
3023 'u', []; ...
3024 'v', []; ...
3025 'w', []; ...
3026 'x', []; ...
3027 'y', []; ...
3028 'z', []; ...
3029 };
3030 argout1 = FillMissingFields(contextName, defPref);
3031
3032 case 'TopoLayoutOptions'
3033 defPref = struct(...
3034 'TimeWindow', [], ...
3035 'WhiteBackground', 0, ...
3036 'ShowRefLines', 1, ...
3037 'ShowLegend', 1, ...
3038 'ContourLines', 10);
3039 argout1 = FillMissingFields(contextName, defPref);
3040
3041 case 'StatThreshOptions'
3042 defPref = struct(...
3043 'pThreshold', .05, ...
3044 'durThreshold', 0, ...
3045 'Correction', 'fdr', ...
3046 'Control', [1 2 3]);
3047 argout1 = FillMissingFields(contextName, defPref);
3048 % Make sure that Control is not a string (previous brainstorm version)
3049 if ischar(argout1.Control)
3050 argout1.Control = defPref.Control;
3051 end
3052 % Make sure that 'no' is used instead of 'none' (previous brainstorm version)
3053 if strcmpi(argout1.Correction, 'none')
3054 argout1.Correction = 'no';
3055 end
3056
3057 case 'ContactSheetOptions'
3058 defPref = struct(...
3059 'nImages', 20, ...
3060 'TimeRange', [], ...
3061 'SkipVolume', 0.2);
3062 argout1 = FillMissingFields(contextName, defPref);
3063
3064 case 'ProcessOptions'
3065 defPref = struct(...
3066 'SavedParam', struct(), ...
3067 'MaxBlockSize', 100 / 8 * 1024 * 1024, ... % 100Mb
3068 'LastMaxBlockSize', 100 / 8 * 1024 * 1024); % 100Mb
3069 argout1 = FillMissingFields(contextName, defPref);
3070
3071 case 'ImportEegRawOptions'
3072 defPref = struct(...
3073 'isCanceled', 0, ...
3074 'BaselineDuration', 0, ...
3075 'SamplingRate', 1000, ...
3076 'MatrixOrientation', 'channelXtime', ... % {'channelXtime', 'timeXchannel'}
3077 'VoltageUnits', 'V', ... % {'\muV', 'mV', 'V'}
3078 'SkipLines', 0, ...
3079 'nAvg', 1, ...
3080 'isChannelName', 0); % 1 if the first entry contains the channel name
3081 argout1 = FillMissingFields(contextName, defPref);
3082
3083 case 'BugReportOptions'
3084 defPref = struct(...
3085 'isEnabled', 0, ...
3086 'SmtpServer', 'mailhost.chups.jussieu.fr', ...
3087 'UserEmail', '');
3088 argout1 = FillMissingFields(contextName, defPref);
3089
3090 case 'DefaultSurfaceDisplay'
3091 defPref = struct(...
3092 'SurfShowSulci', 1, ...
3093 'SurfSmoothValue', 0, ...
3094 'DataThreshold', 0.5, ...
3095 'SizeThreshold', 1, ...
3096 'DataAlpha', 0);
3097 argout1 = FillMissingFields(contextName, defPref);
3098
3099 case 'MagneticExtrapOptions'
3100 defPref = struct(...
3101 'ForceWhitening', 0, ...
3102 'EpsilonValue', 0.0001);
3103 argout1 = FillMissingFields(contextName, defPref);
3104
3105 case 'DefaultFreqBands'
3106 argout1 = {...
3107 'delta', '2, 4', 'mean'; ...
3108 'theta', '5, 7', 'mean'; ...
3109 'alpha', '8, 12', 'mean'; ...
3110 'beta', '15, 29', 'mean'; ...
3111 'gamma1', '30, 59', 'mean'; ...
3112 'gamma2', '60, 90', 'mean'};
3113
3114 case 'TimefreqOptions_morlet'
3115 defPref.isTimeBands = 0;
3116 defPref.isFreqBands = 0;
3117 defPref.isFreqLog = 0;
3118 defPref.TimeBands = {};
3119 defPref.Freqs = '1:1:60';
3120 defPref.FreqsLog = '1:40:150';
3121 defPref.FreqBands = bst_get('DefaultFreqBands');
3122 defPref.Measure = 'power';
3123 defPref.SaveKernel = 0;
3124 defPref.Output = 'all';
3125 defPref.RemoveEvoked = 0;
3126 defPref.ClusterFuncTime = 'after';
3127 defPref.MorletFc = 1;
3128 defPref.MorletFwhmTc = 3;
3129 argout1 = FillMissingFields(contextName, defPref);
3130 if isempty(argout1.Freqs)
3131 argout1.Freqs = defPref.Freqs;
3132 end
3133 if ~isempty(argout1.FreqBands) && ~ischar(argout1.FreqBands{1,2})
3134 argout1.FreqBands = defPref.FreqBands;
3135 end
3136
3137 case 'TimefreqOptions_hilbert'
3138 defPref.isTimeBands = 0;
3139 defPref.isFreqBands = 1;
3140 defPref.isFreqLog = 0;
3141 defPref.TimeBands = {};
3142 defPref.Freqs = [];
3143 defPref.FreqsLog = [];
3144 defPref.FreqBands = bst_get('DefaultFreqBands');
3145 defPref.Measure = 'power';
3146 defPref.SaveKernel = 0;
3147 defPref.Output = 'all';
3148 defPref.RemoveEvoked = 0;
3149 defPref.ClusterFuncTime = 'after';
3150 argout1 = FillMissingFields(contextName, defPref);
3151 if isempty(argout1.Freqs)
3152 argout1.Freqs = defPref.Freqs;
3153 end
3154 if ~isempty(argout1.FreqBands) && ~ischar(argout1.FreqBands{1,2})
3155 argout1.FreqBands = defPref.FreqBands;
3156 end
3157
3158 case 'TimefreqOptions_plv'
3159 defPref.isTimeBands = 0;
3160 defPref.isFreqBands = 1;
3161 defPref.isFreqLog = 0;
3162 defPref.TimeBands = {};
3163 defPref.Freqs = [];
3164 defPref.FreqsLog = [];
3165 defPref.FreqBands = bst_get('DefaultFreqBands');
3166 defPref.Measure = 'other';
3167 defPref.SaveKernel = 0;
3168 defPref.Output = 'all';
3169 defPref.ClusterFuncTime = 'after';
3170 argout1 = FillMissingFields(contextName, defPref);
3171 if isempty(argout1.Freqs)
3172 argout1.Freqs = defPref.Freqs;
3173 end
3174 if ~isempty(argout1.FreqBands) && ~ischar(argout1.FreqBands{1,2})
3175 argout1.FreqBands = defPref.FreqBands;
3176 end
3177
3178 case 'TimefreqOptions_fft'
3179 defPref.isTimeBands = 0;
3180 defPref.isFreqBands = 0;
3181 defPref.isFreqLog = 0;
3182 defPref.TimeBands = {};
3183 defPref.Freqs = [];
3184 defPref.FreqsLog = [];
3185 defPref.FreqBands = bst_get('DefaultFreqBands');
3186 defPref.Measure = 'power';
3187 defPref.Output = 'all';
3188 defPref.ClusterFuncTime = 'after';
3189 argout1 = FillMissingFields(contextName, defPref);
3190 if isempty(argout1.Freqs)
3191 argout1.Freqs = defPref.Freqs;
3192 end
3193 if ~isempty(argout1.FreqBands) && ~ischar(argout1.FreqBands{1,2})
3194 argout1.FreqBands = defPref.FreqBands;
3195 end
3196
3197 case 'TimefreqOptions_psd'
3198 defPref.isTimeBands = 0;
3199 defPref.isFreqBands = 0;
3200 defPref.isFreqLog = 0;
3201 defPref.TimeBands = {};
3202 defPref.Freqs = [];
3203 defPref.FreqsLog = [];
3204 defPref.FreqBands = bst_get('DefaultFreqBands');
3205 defPref.Measure = 'power';
3206 defPref.Output = 'all';
3207 defPref.ClusterFuncTime = 'after';
3208 argout1 = FillMissingFields(contextName, defPref);
3209 if isempty(argout1.Freqs)
3210 argout1.Freqs = defPref.Freqs;
3211 end
3212 if ~isempty(argout1.FreqBands) && ~ischar(argout1.FreqBands{1,2})
3213 argout1.FreqBands = defPref.FreqBands;
3214 end
3215
3216 case 'ExportBidsOptions'
3217 defPref.ProjName = [];
3218 defPref.ProjID = [];
3219 defPref.ProjDesc = [];
3220 defPref.Categories = [];
3221 defPref.JsonDataset = ['{' 10 ' "License": "PD"' 10 '}'];
3222 defPref.JsonMeg = ['{' 10 ' "TaskDescription": "My task"' 10 '}'];
3223 argout1 = FillMissingFields(contextName, defPref);
3224
3225 case 'OpenMEEGOptions'
3226 defPref.BemFiles = {};
3227 defPref.BemNames = {'Scalp', 'Skull', 'Brain'};
3228 defPref.BemCond = [1, 0.0125, 1];
3229 defPref.BemSelect = [1 1 1];
3230 defPref.isAdjoint = 0;
3231 defPref.isAdaptative = 1;
3232 defPref.isSplit = 0;
3233 defPref.SplitLength = 4000;
3234 argout1 = FillMissingFields(contextName, defPref);
3235
3236 case 'DuneuroOptions'
3237 defPref = duneuro_defaults();
3238 argout1 = FillMissingFields(contextName, defPref);
3239
3240 case 'GridOptions_dipfit'
3241 defPref = struct(...
3242 'Method', 'isotropic', ...
3243 'nLayers', 17, ...
3244 'Reduction', 3, ...
3245 'nVerticesInit', 4000, ...
3246 'Resolution', 0.020, ...
3247 'FileName', '');
3248 argout1 = FillMissingFields(contextName, defPref);
3249
3250 case 'GridOptions_headmodel'
3251 defPref = struct(...
3252 'Method', 'isotropic', ...
3253 'nLayers', 17, ...
3254 'Reduction', 3, ...
3255 'nVerticesInit', 4000, ...
3256 'Resolution', 0.005, ...
3257 'FileName', '');
3258 argout1 = FillMissingFields(contextName, defPref);
3259
3260 case 'MriOptions'
3261 defPref = struct(...
3262 'isRadioOrient', 0, ...
3263 'isMipAnatomy', 0, ...
3264 'isMipFunctional', 0, ...
3265 'OverlaySmooth', 0, ...
3266 'InterpDownsample', 3, ...
3267 'DistanceThresh', 6, ...
3268 'UpsampleImage', 0, ...
3269 'DefaultAtlas', []);
3270 argout1 = FillMissingFields(contextName, defPref);
3271
3272 case 'DigitizeOptions'
3273 defPref = struct(...
3274 'ComPort', 'COM1', ...
3275 'ComRate', 9600, ...
3276 'ComByteCount', 94, ... % 47 bytes * 2 receivers
3277 'UnitType', 'fastrak', ...
3278 'PatientId', 'S001', ...
3279 'nFidSets', 2, ...
3280 'isBeep', 1, ...
3281 'isMEG', 1, ...
3282 'isSimulate', 0, ...
3283 'Montages', [...
3284 struct('Name', 'No EEG', ...
3285 'Labels', []), ...
3286 struct('Name', 'Default', ...
3287 'Labels', [])], ...
3288 'iMontage', 1);
3289 argout1 = FillMissingFields(contextName, defPref);
3290
3291 case 'NodelistOptions'
3292 defPref = struct(...
3293 'String', '', ... % What to search for
3294 'Target', 'Comment', ... % What field to search for: {'FileName', 'Comment'}
3295 'Action', 'Select'); % What to do with the filtered files: {'Select', 'Exclude'}
3296 argout1 = FillMissingFields(contextName, defPref);
3297
3298 case 'ReadOnly'
3299 if isfield(GlobalData.DataBase, 'isReadOnly')
3300 argout1 = GlobalData.DataBase.isReadOnly;
3301 else
3302 argout1 = 0;
3303 end
3304
3305 case 'LastPsdDisplayFunction'
3306 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'LastPsdDisplayFunction')
3307 argout1 = GlobalData.Preferences.LastPsdDisplayFunction;
3308 else
3309 argout1 = [];
3310 end
3311
3312 case 'PlotlyCredentials'
3313 try
3314 creds = loadplotlycredentials();
3315 argout1 = creds.username;
3316 argout2 = creds.api_key;
3317 catch
3318 argout1 = '';
3319 argout2 = '';
3320 end
3321
3322 try
3323 config = loadplotlyconfig();
3324 argout3 = config.plotly_domain;
3325 catch
3326 argout3 = '';
3327 end
3328
3329 case 'KlustersExecutable'
3330 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'KlustersExecutable')
3331 argout1 = GlobalData.Preferences.KlustersExecutable;
3332 else
3333 argout1 = [];
3334 end
3335
3336
3337 %% ===== FILE FILTERS =====
3338 case 'FileFilters'
3339 switch lower(varargin{2})
3340 case 'mri'
3341 argout1 = {...
3342 {'.img'}, 'MRI: Analyze (*.img/*.hdr)', 'Analyze'; ...
3343 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3344 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3345 {'.mri'}, 'MRI: CTF (*.mri)', 'CTF'; ...
3346 {'.mat'}, 'MRI: FieldTrip (*.mat)', 'FT-MRI'; ...
3347 {'.mgh','.mgz'}, 'MRI: MGH (*.mgh,*.mgz)', 'MGH'; ...
3348 {'.mnc', '.mni'}, 'MRI: MNI (*.mnc,*.mni)', 'MINC'; ...
3349 {'.nii','.gz'}, 'MRI: NIfTI-1 (*.nii;*.nii.gz)', 'Nifti1'; ...
3350 {'_subjectimage'}, 'MRI: Brainstorm (*subjectimage*.mat)', 'BST'; ...
3351 {'*'}, 'MRI: DICOM (SPM converter)', 'DICOM-SPM'; ...
3352 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'All MRI files (subject space)', 'ALL'; ...
3353 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'All MRI files (MNI space)', 'ALL-MNI'; ...
3354 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume atlas (subject space)', 'ALL-ATLAS'; ...
3355 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume atlas (MNI space)', 'ALL-MNI-ATLAS'; ...
3356 };
3357 case 'mriout'
3358 argout1 = {...
3359 {'.img'}, 'MRI: Analyze (*.img/*.hdr)', 'Analyze'; ...
3360 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3361 {'.mri'}, 'MRI: CTF (*.mri)', 'CTF'; ...
3362 {'.mat'}, 'MRI: FieldTrip (*.mat)', 'FT-MRI'; ...
3363 {'.nii'}, 'MRI: NIfTI-1 (*.nii)', 'Nifti1'...
3364 };
3365 case 'anatin'
3366 argout1 = {...
3367 {'.folder'}, 'FreeSurfer', 'FreeSurfer-fast'; ...
3368 {'.folder'}, 'FreeSurfer + Volume atlases', 'FreeSurfer'; ...
3369 {'.folder'}, 'FreeSurfer + Volume atlases + Thickness', 'FreeSurfer+Thick'; ...
3370 {'.folder'}, 'BrainSuite', 'BrainSuite-fast'; ...
3371 {'.folder'}, 'BrainSuite + Volume atlases', 'BrainSuite'; ...
3372 {'.folder'}, 'BrainVISA', 'BrainVISA'; ...
3373 {'.folder'}, 'CAT12', 'CAT12'; ...
3374 {'.folder'}, 'CAT12 + Thickness', 'CAT12+Thick'; ...
3375 {'.folder'}, 'CIVET', 'CIVET'; ...
3376 {'.folder'}, 'CIVET + Thickness', 'CIVET+Thick'; ...
3377 {'.folder'}, 'HCP MEG/anatomy (pipeline v3)', 'HCPv3'; ...
3378 {'.folder'}, 'SimNIBS', 'SimNIBS'; ...
3379 };
3380 case 'source4d'
3381 argout1 = {...
3382 {'.folder'}, 'NIfTI-1 (*.nii)', 'Nifti1';...
3383 {'.folder'}, 'Analyze (*.img/*.hdr)', 'Analyze'; ...
3384 {'.folder'}, 'Matlab 4D matrix (*voltime*.mat)', 'BST'; ...
3385 };
3386
3387 case 'surface'
3388 argout1 = {...
3389 {'.mesh'}, 'BrainVISA (*.mesh)', 'MESH'; ...
3390 {'_tess', '_head', '_scalp', '_brain', '_cortex', '_innerskull', '_outerskull'}, 'Brainstorm (*.mat)', 'BST'; ...
3391 {'.dfs'}, 'BrainSuite (*.dfs)', 'DFS'; ...
3392 {'.dsgl'}, 'BrainSuite old (*.dsgl)', 'DSGL'; ...
3393 {'.bd0','.bd1','.bd2','.bd3','.bd4','.bd5','.bd6','.bd7','.bd8','.bd9', ...
3394 '.s00','.s01','.s02','.s03','.s04','.s05','.s06','.s07','.s08','.s09'}, ...
3395 'Curry BEM (*.db*;*.s0*)', 'CURRY-BEM';
3396 {'.vtk'}, 'FSL: VTK (*.vtk)', 'VTK'; ...
3397 {'*'}, 'FreeSurfer (*.*)', 'FS';
3398 {'.off'}, 'Geomview OFF (*.off)', 'OFF'; ...
3399 {'.gii'}, 'GIfTI / MRI coordinates (*.gii)', 'GII'; ...
3400 {'.gii'}, 'GIfTI / MNI coordinates (*.gii)', 'GII-MNI'; ...
3401 {'.gii'}, 'GIfTI / World coordinates (*.gii)', 'GII-WORLD'; ...
3402 {'.fif'}, 'MNE (*.fif)', 'FIF'; ...
3403 {'.obj'}, 'MNI OBJ (*.obj)', 'MNIOBJ'; ...
3404 {'.msh'}, 'SimNIBS Gmsh4 (*.msh)', 'SIMNIBS'; ...
3405 {'.tri'}, 'TRI (*.tri)', 'TRI'; ...
3406 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (subject space)', 'MRI-MASK'; ...
3407 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (MNI space)', 'MRI-MASK-MNI'; ...
3408 {'.nwbaux'}, 'Neurodata Without Borders (*.nwbaux)', 'NWB'; ...
3409 {'*'}, 'All surface files (*.*)', 'ALL'; ...
3410 };
3411
3412 case 'surfaceout'
3413 argout1 = {...
3414 {'.mesh'}, 'BrainVISA (*.mesh)', 'MESH'; ...
3415 {'.dfs'}, 'BrainSuite (*.dfs)', 'DFS'; ...
3416 {'.fs'}, 'FreeSurfer (*.fs)', 'FS'
3417 {'.off'}, 'Geomview OFF (*.off)', 'OFF'; ...
3418 {'.gii'}, 'GIfTI (*.gii)', 'GII'; ...
3419 {'.tri'}, 'TRI (*.tri)', 'TRI'; ...
3420 };
3421
3422 case 'data'
3423 argout1 = {...
3424 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3425 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF'; ...
3426 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3427 {'.mat'}, 'MEG/EEG: FieldTrip (*.mat)', 'FT-TIMELOCK'; ...
3428 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3429 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3430 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3431 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3432 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3433 {'.hdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.hdf5)', 'MEGSCAN-HDF5'; ...
3434 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3435 {'.adicht'}, 'EEG: ADInstruments LabChart (*.adicht)', 'EEG-ADICHT'; ...
3436 {'.msr'}, 'EEG: ANT ASA (*.msr)', 'EEG-ANT-MSR'; ...
3437 {'.cnt','.avr'}, 'EEG: ANT EEProbe (*.cnt;*.avr)', 'EEG-ANT-CNT'; ...
3438 {'*'}, 'EEG: ASCII text (*.*)', 'EEG-ASCII'; ...
3439 {'.bdf'}, 'EEG: BDF (*.bdf)', 'EEG-BDF'; ...
3440 {'.avr','.mux','.mul'}, 'EEG: BESA exports (*.avr;*.mul;*.mux)', 'EEG-BESA'; ...
3441 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Blackrock NeuroPort (*.nsX/*.nev)', 'EEG-BLACKROCK';
3442 {'.eeg','.dat'}, 'EEG: BrainAmp (*.eeg;*.dat)', 'EEG-BRAINAMP'; ...
3443 {'.txt'}, 'EEG: BrainVision Analyzer (*.txt)', 'EEG-BRAINVISION'; ...
3444 {'.sef','.ep','.eph'}, 'EEG: Cartool (*.sef;*.ep;*.eph)', 'EEG-CARTOOL'; ...
3445 {'.dat','.cdt'}, 'EEG: Curry (*.dat;*.cdt)', 'EEG-CURRY'; ...
3446 {'.smr','.son'}, 'EEG: CED Spike2 old 32bit (*.smr;*.son)', 'EEG-SMR'; ...
3447 {'.smr','.smrx'}, 'EEG: CED Spike2 new 64bit (*.smr;*.smrx)', 'EEG-SMRX'; ...
3448 {'.rda'}, 'EEG: Compumedics ProFusion Sleep (*.rda)', 'EEG-COMPUMEDICS-PFS'; ...
3449 {'.bin'}, 'EEG: Deltamed Coherence-Neurofile (*.bin)', 'EEG-DELTAMED'; ...
3450 {'.edf','.rec'}, 'EEG: EDF / EDF+ (*.rec;*.edf)', 'EEG-EDF'; ...
3451 {'.set'}, 'EEG: EEGLAB (*.set)', 'EEG-EEGLAB'; ...
3452 {'.raw'}, 'EEG: EGI Netstation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3453 {'.mff','.bin'}, 'EEG: EGI-Philips (*.mff)', 'EEG-EGI-MFF'; ...
3454 {'.edf'}, 'EEG: EmotivPRO (*.edf)', 'EEG-EMOTIV'; ...
3455 {'.erp','.hdr'}, 'EEG: ERPCenter (*.hdr;*.erp)', 'EEG-ERPCENTER'; ...
3456 {'.erp'}, 'EEG: ERPLab (*.erp)', 'EEG-ERPLAB'; ...
3457 {'.mat','.hdf5'}, 'EEG: g.tec Matlab (*.mat,*.hdf5)', 'EEG-GTEC'; ...
3458 {'.rhd','.rhs'}, 'EEG: Intan (*.rhd,*.rhs)', 'EEG-INTAN'; ...
3459 {'.mb2'}, 'EEG: MANSCAN (*.mb2)', 'EEG-MANSCAN'; ...
3460 {'.trc'}, 'EEG: Micromed (*.trc)', 'EEG-MICROMED'; ...
3461 {'.mat'}, 'EEG: Matlab matrix (*.mat)', 'EEG-MAT'; ...
3462 {'.csv'}, 'EEG: Muse (*.csv)', 'EEG-MUSE-CSV'; ...
3463 {'.ncs'}, 'EEG: Neuralynx (*.ncs)', 'EEG-NEURALYNX'; ...
3464 {'.bin'}, 'EEG: NeurOne session folder', 'EEG-NEURONE'; ...
3465 {'.cnt','.avg','.eeg','.dat'}, 'EEG: Neuroscan (*.cnt;*.eeg;*.avg;*.dat)', 'EEG-NEUROSCAN'; ...
3466 {'.eeg','.dat'}, 'EEG: NeuroScope (*.eeg;*.dat)', 'EEG-NEUROSCOPE'; ...
3467 {'.e'}, 'EEG: Nicolet (*.e)', 'EEG-NICOLET'; ...
3468 {'.eeg'}, 'EEG: Nihon Kohden (*.eeg)', 'EEG-NK'; ...
3469 {'.dat'}, 'EEG: Open Ephys flat binary (*.dat)', 'EEG-OEBIN'; ...
3470 {'.plx','.pl2'}, 'EEG: Plexon (*.plx;*.pl2)', 'EEG-PLEXON'; ...
3471 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Ripple Trellis (*.nsX/*.nev)', 'EEG-RIPPLE'; ...
3472 {'.h5'}, 'EEG: The Virtual Brain (*_TimeSeriesEEG.h5)', 'EEG-TVB'; ...
3473 {'.csv'}, 'EEG: Wearable Sensing (*.csv)', 'EEG-WS-CSV'; ...
3474 {'.nirs'}, 'NIRS: Brainsight (*.nirs)', 'NIRS-BRS'; ...
3475 {'.bnirs','.jnirs','.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3476 {'.edf'}, 'EyeLink eye tracker (*.edf)', 'EYELINK'; ...
3477 };
3478 case 'raw'
3479 argout1 = {...
3480 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3481 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF'; ...
3482 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3483 {'.mat'}, 'MEG/EEG: FieldTrip (*.mat)', 'FT-TIMELOCK'; ...
3484 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3485 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3486 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3487 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3488 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3489 {'.hdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.hdf5)', 'MEGSCAN-HDF5'; ...
3490 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3491 {'.adicht'}, 'EEG: ADInstruments LabChart (*.adicht)', 'EEG-ADICHT'; ...
3492 {'.msr'}, 'EEG: ANT ASA (*.msr)', 'EEG-ANT-MSR'; ...
3493 {'.cnt','.avr'}, 'EEG: ANT EEProbe (*.cnt;*.avr)', 'EEG-ANT-CNT'; ...
3494 {'*'}, 'EEG: ASCII text (*.*)', 'EEG-ASCII'; ...
3495 {'.bdf'}, 'EEG: BDF (*.bdf)', 'EEG-BDF'; ...
3496 {'.avr','.mux','.mul'}, 'EEG: BESA exports (*.avr;*.mul;*.mux)', 'EEG-BESA'; ...
3497 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Blackrock NeuroPort (*.nsX/*.nev)', 'EEG-BLACKROCK';
3498 {'.eeg','.dat'}, 'EEG: BrainAmp (*.eeg;*.dat)', 'EEG-BRAINAMP'; ...
3499 {'.txt'}, 'EEG: BrainVision Analyzer (*.txt)', 'EEG-BRAINVISION'; ...
3500 {'.sef','.ep','.eph'}, 'EEG: Cartool (*.sef;*.ep;*.eph)', 'EEG-CARTOOL'; ...
3501 {'.smr','.son'}, 'EEG: CED Spike2 old 32bit (*.smr;*.son)', 'EEG-SMR'; ...
3502 {'.smr','.smrx'}, 'EEG: CED Spike2 new 64bit (*.smr;*.smrx)', 'EEG-SMRX'; ...
3503 {'.rda'}, 'EEG: Compumedics ProFusion Sleep (*.rda)', 'EEG-COMPUMEDICS-PFS'; ...
3504 {'.dat','.cdt'}, 'EEG: Curry (*.dat;*.cdt)', 'EEG-CURRY'; ...
3505 {'.bin'}, 'EEG: Deltamed Coherence-Neurofile (*.bin)', 'EEG-DELTAMED'; ...
3506 {'.edf','.rec'}, 'EEG: EDF / EDF+ (*.rec;*.edf)', 'EEG-EDF'; ...
3507 {'.set'}, 'EEG: EEGLAB (*.set)', 'EEG-EEGLAB'; ...
3508 {'.raw'}, 'EEG: EGI Netstation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3509 {'.mff','.bin'}, 'EEG: EGI-Philips (*.mff)', 'EEG-EGI-MFF'; ...
3510 {'.edf'}, 'EEG: EmotivPRO (*.edf)', 'EEG-EMOTIV'; ...
3511 {'.mat','.hdf5'}, 'EEG: g.tec Matlab (*.mat,*.hdf5)', 'EEG-GTEC'; ...
3512 {'.rhd','.rhs'}, 'EEG: Intan (*.rhd,*.rhs)', 'EEG-INTAN'; ...
3513 {'.mb2'}, 'EEG: MANSCAN (*.mb2)', 'EEG-MANSCAN'; ...
3514 {'.mat'}, 'EEG: Matlab matrix (*.mat)', 'EEG-MAT'; ...
3515 {'.csv'}, 'EEG: Muse (*.csv)', 'EEG-MUSE-CSV'; ...
3516 {'.trc'}, 'EEG: Micromed (*.trc)', 'EEG-MICROMED'; ...
3517 {'.ncs'}, 'EEG: Neuralynx (*.ncs)', 'EEG-NEURALYNX'; ...
3518 {'.nwb'}, 'EEG: Neurodata Without Borders (*.nwb)','NWB'; ...
3519 {'.bin'}, 'EEG: NeurOne session folder', 'EEG-NEURONE'; ...
3520 {'.cnt','.avg','.eeg','.dat'}, 'EEG: Neuroscan (*.cnt;*.eeg;*.avg;*.dat)', 'EEG-NEUROSCAN'; ...
3521 {'.eeg','.dat'}, 'EEG: NeuroScope (*.eeg;*.dat)', 'EEG-NEUROSCOPE'; ...
3522 {'.e'}, 'EEG: Nicolet (*.e)', 'EEG-NICOLET'; ...
3523 {'.eeg'}, 'EEG: Nihon Kohden (*.eeg)', 'EEG-NK'; ...
3524 {'.dat'}, 'EEG: Open Ephys flat binary (*.dat)', 'EEG-OEBIN'; ...
3525 {'.plx','.pl2'}, 'EEG: Plexon (*.plx;.pl2)' 'EEG-PLEXON'; ...
3526 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Ripple Trellis (*.nsX/*.nev)', 'EEG-RIPPLE'; ...
3527 {'.h5'}, 'EEG: The Virtual Brain (*_TimeSeriesEEG.h5)', 'EEG-TVB'; ...
3528 {'.tbk'}, 'EEG: Tucker Davis Technologies (*.tbk)', 'EEG-TDT'; ...
3529 {'.csv'}, 'EEG: Wearable Sensing (*.csv)', 'EEG-WS-CSV'; ...
3530 {'.trc','.eeg','.e','.bin','.rda','.edf','.bdf'}, 'SEEG: Deltamed/Micromed/NK/Nicolet/BrainAmp/EDF', 'SEEG-ALL'; ...
3531 {'.trc','.eeg','.e','.bin','.rda','.edf','.bdf'}, 'ECOG: Deltamed/Micromed/NK/Nicolet/BrainAmp/EDF', 'ECOG-ALL'; ...
3532 {'.nirs'}, 'NIRS: Brainsight (*.nirs)', 'NIRS-BRS'; ...
3533 {'.bnirs','.jnirs','.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3534 {'.edf'}, 'EyeLink eye tracker (*.edf)', 'EYELINK'; ...
3535 };
3536
3537 case 'dataout'
3538 argout1 = {...
3539 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3540 {'.mat'}, 'MEG/EEG: FieldTrip timelock (*.mat)', 'FT-TIMELOCK'; ...
3541 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3542 {'.eeg'}, 'EEG: BrainVision BrainAmp (*.eeg)', 'EEG-BRAINAMP'; ...
3543 {'.eph'}, 'EEG: Cartool EPH (*.eph)', 'EEG-CARTOOL-EPH'; ...
3544 {'.raw'}, 'EEG: EGI NetStation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3545 {'.edf'}, 'EEG: European Data Format (*.edf)', 'EEG-EDF'; ...
3546 {'.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3547 {'.txt'}, 'ASCII: Space-separated, fixed column size (*.txt)', 'ASCII-SPC'; ...
3548 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3549 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3550 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3551 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3552 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3553 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3554 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3555 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3556 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3557 {'_timeseries'}, 'Brainstorm matrix (*timeseries*.mat)', 'BST'; ...
3558 };
3559 case 'rawout'
3560 argout1 = {...
3561 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3562 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3563 {'.eeg'}, 'EEG: BrainVision BrainAmp (*.eeg)', 'EEG-BRAINAMP'; ...
3564 {'.raw'}, 'EEG: EGI NetStation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3565 {'.edf'}, 'EEG: European Data Format (*.edf)', 'EEG-EDF'; ...
3566 {'.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3567 };
3568 case 'events'
3569 argout1 = {...
3570 {'.trg'}, 'ANT EEProbe (*.trg)', 'ANT'; ...
3571 {'.mrk'}, 'AnyWave (*.mrk)', 'ANYWAVE'; ...
3572 {'.evt'}, 'BESA (*.evt)', 'BESA'; ...
3573 {'.tsv'}, 'BIDS events: onset, duration, trial_type, channel (*.tsv)', 'BIDS'; ...
3574 {'.vmrk'}, 'BrainVision BrainAmp (*.vmrk)', 'BRAINAMP'; ...
3575 {'_events'}, 'Brainstorm (events*.mat)', 'BST'; ...
3576 {'.mrk'}, 'Cartool (*.mrk)', 'CARTOOL'; ...
3577 {'.mrk'}, 'CTF MarkerFile (*.mrk)', 'CTF'; ...
3578 {'.cef'}, 'Curry (*.cef)', 'CURRY'; ...
3579 {'.eve','.fif'}, 'Elekta-Neuromag MNE (*.eve;*.fif)', 'FIF'; ...
3580 {'.evl','.txt'}, 'Elekta-Neuromag Graph (*.evl;*.txt)', 'GRAPH'; ...
3581 {'.txt','.mat'}, 'FieldTrip trial definition (*.txt;*.mat)', 'TRL'; ...
3582 {'.trg'}, 'KRISS MEG (*.trg)', 'KDF'; ...
3583 {'.ev2'}, 'Neuroscan (*.ev2)', 'NEUROSCAN'; ...
3584 {'.txt'}, 'Nicolet export (*.txt)', 'NICOLET'; ...
3585 {'timestamps.npy'},'Open Ephys (timestamps.npy)', 'OEBIN'; ...
3586 {'.log'}, 'Presentation (*.log)', 'PRESENTATION'; ...
3587 {'.mrk','.sqd','.con','.raw','.ave'}, 'Ricoh (*.mrk;*.sqd;*.con;*.raw;*.ave)', 'RICOH'; ...
3588 {'.txt'}, 'XLTEK export (*.txt)', 'XLTEK'; ...
3589 {'.mrk','.sqd','.con','.raw','.ave'}, 'Yokogawa/KIT (*.mrk;*.sqd;*.con;*.raw;*.ave)', 'KIT'; ...
3590 {'.*'}, 'Array of times (*.mat;*.*)', 'ARRAY-TIMES'; ...
3591 {'.*'}, 'Array of samples (*.mat;*.*)', 'ARRAY-SAMPLES'; ...
3592 {'.txt','.csv'}, 'CSV text file: label, time, duration (*.txt;*.csv)', 'CSV-TIME'; ...
3593 {'.*'}, 'CTF Video Times (.txt)', 'CTFVIDEO'; ...
3594 };
3595 case 'channel'
3596 argout1 = {...
3597 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3598 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF' ; ...
3599 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3600 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3601 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3602 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3603 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3604 {'.hdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.hdf5)', 'MEGSCAN-HDF5'; ...
3605 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3606 {'_channel'}, 'MEG/EEG: Brainstorm (channel*.mat)', 'BST'; ...
3607 {'.elc'}, 'EEG: ANT ASA/Xensor (*.elc)', 'XENSOR'; ...
3608 {'.sfp','.elp','.ela','.eps'}, 'EEG: BESA (*.sfp;*.elp;*.eps/*.ela)', 'BESA'; ...
3609 {'.bvef','.bvct','.txt'}, 'EEG: BrainVision electrode file (*.bvef,*.bvct,*.txt)', 'BRAINVISION'; ...
3610 {'.tsv'}, 'EEG: BIDS electrodes.tsv, subject space mm (*.tsv)', 'BIDS-ORIG-MM'; ...
3611 {'.tsv'}, 'EEG: BIDS electrodes.tsv, MNI space mm (*.tsv)', 'BIDS-MNI-MM'; ...
3612 {'.els','.xyz'}, 'EEG: Cartool (*.els;*.xyz)', 'CARTOOL'; ...
3613 {'.eeg'}, 'EEG: MegDraw (*.eeg)', 'MEGDRAW'; ...
3614 {'.res','.rs3','.pom'}, 'EEG: Curry (*.res;*.rs3;*.pom)', 'CURRY'; ...
3615 {'.ced','.xyz','.set'}, 'EEG: EEGLAB (*.ced;*.xyz;*.set)', 'EEGLAB'; ...
3616 {'.elc'}, 'EEG: EETrak (*.elc)', 'EETRAK'; ...
3617 {'.sfp'}, 'EEG: EGI (*.sfp)', 'EGI'; ...
3618 {'coordinates.xml'}, 'EEG: EGI-Philips (coordinates.xml)', 'MFF'; ...
3619 {'.elp'}, 'EEG: EMSE (*.elp)', 'EMSE'; ...
3620 {'.pts','.csv'}, 'EEG: IntrAnat, subject space (*.pts;*.csv)', 'INTRANAT'; ...
3621 {'.pts','.csv'}, 'EEG: IntrAnat, MNI space (*.pts;*.csv)', 'INTRANAT_MNI'; ...
3622 {'.csv'}, 'EEG: Localite (*.csv)', 'LOCALITE'; ...
3623 {'.dat','.tri','.txt','.asc'}, 'EEG: Neuroscan (*.dat;*.tri;*.txt;*.asc)', 'NEUROSCAN'; ...
3624 {'.pos','.pol','.elp','.txt'}, 'EEG: Polhemus (*.pos;*.pol;*.elp;*.txt)', 'POLHEMUS'; ...
3625 {'.csv'}, 'EEG: SimNIBS (*.csv)', 'SIMNIBS'; ...
3626 {'.h5'}, 'EEG: The Virtual Brain (*_SensorsEEG.h5)', 'TVB'; ...
3627 {'*'}, 'EEG: ASCII: Name,XYZ (*.*)', 'ASCII_NXYZ'; ...
3628 {'*'}, 'EEG: ASCII: Name,XYZ_MNI (*.*)', 'ASCII_NXYZ_MNI'; ...
3629 {'*'}, 'EEG: ASCII: Name,XYZ_World (*.*)', 'ASCII_NXYZ_WORLD'; ...
3630 {'*'}, 'EEG: ASCII: Name,XY (*.*)', 'ASCII_NXY'; ...
3631 {'*'}, 'EEG: ASCII: XYZ (*.*)', 'ASCII_XYZ'; ...
3632 {'*'}, 'EEG: ASCII: XYZ_MNI (*.*)', 'ASCII_XYZ_MNI'; ...
3633 {'*'}, 'EEG: ASCII: XYZ_World (*.*)', 'ASCII_XYZ_WORLD'; ...
3634 {'*'}, 'EEG: ASCII: XY (*.*)', 'ASCII_XY'; ...
3635 {'*'}, 'EEG: ASCII: XYZ,Name (*.*)', 'ASCII_XYZN'; ...
3636 {'*'}, 'EEG: ASCII: XYZ_MNI,Name (*.*)', 'ASCII_XYZN_MNI'; ...
3637 {'*'}, 'EEG: ASCII: XYZ_World,Name (*.*)', 'ASCII_XYZN_WORLD'; ...
3638 {'*'}, 'EEG: ASCII: Name,Theta,Phi (*.*)', 'ASCII_NTP'; ...
3639 {'*'}, 'EEG: ASCII: Theta,Phi (*.*)', 'ASCII_TP'; ...
3640 };
3641 case 'channelout'
3642 argout1 = {...
3643 {'.pos'}, 'EEG+Headshape: Polhemus (*.pos)', 'POLHEMUS'; ...
3644 {'.eeg'}, 'Headshape: MegDraw (*.eeg)', 'MEGDRAW'; ...
3645 {'.pos'}, 'Headshape: Polhemus (*.pos)', 'POLHEMUS-HS'; ...
3646 {'.txt'}, 'Headshape: ASCII: XYZ (*.txt)', 'ASCII_XYZ-HS'; ...
3647 {'.txt'}, 'Headshape: ASCII: XYZ_World (*.txt)', 'ASCII_XYZ_WORLD-HS'; ...
3648 {'.txt'}, 'Headshape: ASCII: Name,XYZ (*.txt)', 'ASCII_NXYZ-HS'; ...
3649 {'.txt'}, 'Headshape: ASCII: Name,XYZ_World (*.txt)', 'ASCII_NXYZ_WORLD-HS'; ...
3650 {'.txt'}, 'Headshape: ASCII: XYZ,Name (*.txt)', 'ASCII_XYZN-HS'; ...
3651 {'.txt'}, 'Headshape: ASCII: XYZ_World,Name (*.txt)', 'ASCII_XYZN_WORLD-HS'; ...
3652 {'.sfp'}, 'EEG: BESA (*.sfp)', 'BESA-SFP'; ...
3653 {'.elp'}, 'EEG: BESA (*.elp)', 'BESA-ELP'; ...
3654 {'.xyz'}, 'EEG: Cartool (*.xyz)', 'CARTOOL-XYZ'; ...
3655 {'.res'}, 'EEG: Curry (*.res)', 'CURRY-RES'; ...
3656 {'.xyz'}, 'EEG: EEGLAB (*.xyz)', 'EEGLAB-XYZ'; ...
3657 {'.sfp'}, 'EEG: EGI (*.sfp)', 'EGI'; ...
3658 {'.txt'}, 'EEG: ASCII: XYZ (*.txt)', 'ASCII_XYZ-EEG'; ...
3659 {'.txt'}, 'EEG: ASCII: XYZ_MNI (*.*)', 'ASCII_XYZ_MNI-EEG'; ...
3660 {'.txt'}, 'EEG: ASCII: XYZ_World (*.*)', 'ASCII_XYZ_WORLD-EEG'; ...
3661 {'.txt'}, 'EEG: ASCII: Name,XYZ (*.txt)', 'ASCII_NXYZ-EEG'; ...
3662 {'.txt'}, 'EEG: ASCII: Name,XYZ_MNI (*.*)', 'ASCII_NXYZ_MNI-EEG'; ...
3663 {'.txt'}, 'EEG: ASCII: Name,XYZ_World (*.*)', 'ASCII_NXYZ_WORLD-EEG'; ...
3664 {'.txt'}, 'EEG: ASCII: XYZ,Name (*.txt)', 'ASCII_XYZN-EEG'; ...
3665 {'.txt'}, 'EEG: ASCII: XYZ_MNI,Name (*.*)', 'ASCII_XYZN_MNI-EEG'; ...
3666 {'.txt'}, 'EEG: ASCII: XYZ_World,Name (*.*)', 'ASCII_XYZN_WORLD-EEG'; ...
3667 {'.txt'}, 'NIRS: Brainsight (*.txt)', 'BRAINSIGHT-TXT'; ...
3668 };
3669 case 'labelin'
3670 argout1 = {...
3671 {'.dfs'}, 'BrainSuite atlas (*.dfs)', 'DFS'; ...
3672 {'.annot'}, 'FreeSurfer atlas (*.annot)', 'FS-ANNOT'; ...
3673 {'.label'}, 'FreeSurfer ROI, single scout (*.label)', 'FS-LABEL-SINGLE'; ...
3674 {'.label'}, 'FreeSurfer ROI, probability map (*.label)', 'FS-LABEL'; ...
3675 {'.gii'}, 'GIfTI texture (*.gii)', 'GII-TEX'; ...
3676 {'.dset'}, 'SUMA atlas (*.dset)', 'DSET'; ...
3677 {'_scout'}, 'Brainstorm scouts (*scout*.mat)', 'BST'; ...
3678 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (dilated, subject space)', 'MRI-MASK'; ...
3679 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (dilated, MNI space)', 'MRI-MASK-MNI'; ...
3680 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (no overlap, subject space)', 'MRI-MASK-NOOVERLAP'; ...
3681 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (no overlap, MNI space)', 'MRI-MASK-NOOVERLAP-MNI'; ...
3682 };
3683 case 'resultsout'
3684 argout1 = {...
3685 {'_sources'}, 'Brainstorm sources (*sources*.mat)', 'BST'; ...
3686 {'.mat'}, 'FieldTrip sources (*.mat)', 'FT-SOURCES'; ...
3687 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3688 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3689 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3690 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3691 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3692 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3693 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3694 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3695 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3696 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3697 };
3698 case 'timefreqout'
3699 argout1 = {...
3700 {'_timefreq'}, 'Brainstorm structure (*timefreq*.mat)', 'BST'; ...
3701 {'.mat'}, 'FieldTrip freq (*.mat)', 'FT-FREQ'; ...
3702 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3703 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3704 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3705 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3706 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3707 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3708 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3709 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3710 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3711 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3712 };
3713 case 'matrixout'
3714 argout1 = {...
3715 {'_matrix'}, 'Brainstorm structure (*matrix*.mat)', 'BST'; ...
3716 {'.mat'}, 'FieldTrip timelock (*.mat)', 'FT-TIMELOCK'; ...
3717 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3718 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3719 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3720 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3721 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3722 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3723 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3724 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3725 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3726 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3727 };
3728 case 'montagein'
3729 argout1 = {...
3730 {'.sel'}, 'MNE selection files (*.sel)', 'MNE'; ...
3731 {'.mon'}, 'Text montage files (*.mon)', 'MON'; ...
3732 {'_montage'}, 'Brainstorm montage files (montage_*.mat)', 'BST';
3733 {'.csv'}, 'Comma-separated montage files (*.csv)', 'CSV'; ...
3734 {'.xml'}, 'Compumedics ProFusion montages (*.xml)', 'EEG-COMPUMEDICS-PFS'};
3735 case 'montageout'
3736 argout1 = {...
3737 {'.sel'}, 'MNE selection files (*.sel)', 'MNE'; ...
3738 {'.mon'}, 'Text montage files (*.mon)', 'MON'; ...
3739 {'_montage'}, 'Brainstorm montage files (montage_*.mat)', 'BST'};
3740 case 'fibers'
3741 argout1 = {...
3742 {'.trk'}, 'TrackVis (*.trk)', 'TRK'; ...
3743 {'_fibers'}, 'Brainstorm fibers files (fibers_*.mat)', 'BST'};
3744 end
3745
3746
3747 %% ===== FONTS =====
3748 case 'FigFont'
3749 if ispc
3750 argout1 = 8;
3751 else
3752 argout1 = 9;
3753 end
3754 InterfaceScaling = bst_get('InterfaceScaling');
3755 if (InterfaceScaling ~= 100)
3756 argout1 = argout1 * InterfaceScaling / 100;
3757 end
3758
3759 case 'Font'
3760 % Default font size
3761 if (nargin < 2)
3762 if strncmp(computer,'MAC',3)
3763 fontSize = 12;
3764 else
3765 fontSize = 11;
3766 end
3767 % Font size in input
3768 else
3769 fontSize = varargin{2};
3770 end
3771 % Adjust for interface scaling
3772 fontSize = fontSize * bst_get('InterfaceScaling') / 100;
3773
3774 % Font types
3775 fontTypes = {};
3776 if (nargin >= 3)
3777 fontTypes{end + 1} = varargin{3};
3778 end
3779 fontTypes{end + 1} = 'Arial'; % Default font
3780 fontTypes{end + 1} = 'Liberation Sans'; % Free Arial substitute
3781
3782 % Check for cached font
3783 foundFont = 0;
3784 for iFont = 1 : length(fontTypes)
3785 strCache = strrep(sprintf('%s%d', fontTypes{iFont}, round(fontSize*100)), ' ', '_');
3786 if ~isempty(GlobalData) && isfield(GlobalData, 'Program') && isfield(GlobalData.Program, 'FontCache') && isfield(GlobalData.Program.FontCache, strCache)
3787 argout1 = GlobalData.Program.FontCache.(strCache);
3788 foundFont = 1;
3789 break;
3790 end
3791 end
3792
3793 % If font not cached, find first supported font
3794 if ~foundFont
3795 ge = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
3796 allFonts = cell(ge.getAvailableFontFamilyNames());
3797
3798 for iFont = 1 : length(fontTypes)
3799 if any(strcmp(fontTypes{iFont}, allFonts))
3800 fontType = fontTypes{iFont};
3801 foundFont = 1;
3802 break;
3803 end
3804 end
3805
3806 if ~foundFont
3807 fontType = 'SansSerif'; % If nothing else works.
3808 end
3809
3810 strCache = strrep(sprintf('%s%d', fontType, round(fontSize*100)), ' ', '_');
3811 argout1 = java.awt.Font(fontType, java.awt.Font.PLAIN, fontSize);
3812 GlobalData.Program.FontCache.(strCache) = argout1;
3813 end
3814
3815 %% ==== PANEL CONTAINERS ====
3816 case 'PanelContainer'
3817 % Get Brainstorm GUI context structure
3818 bst_GUI = GlobalData.Program.GUI;
3819 if (isempty(bst_GUI) || ~isfield(bst_GUI, 'panelContainers'))
3820 error('Brainstorm GUI is not yet initialized');
3821 end
3822
3823 % Get ContainerName in argument
3824 if ((nargin >= 2) && (ischar(varargin{2})))
3825 ContainerName = varargin{2};
3826 % If no container name in argument : just display all the container names
3827 else
3828 disp('Registered panel containers :');
3829 for iContainer = 1:length(bst_GUI.panelContainers)
3830 disp([' - ' bst_GUI.panelContainers(iContainer).name]);
3831 end
3832 return
3833 end
3834
3835 % Look for containerName in all the registered panel containers
3836 iContainer = 1;
3837 found = 0;
3838 while (~found (iContainer <= length(bst_GUI.panelContainers)))
3839 if (strcmpi(ContainerName, bst_GUI.panelContainers(iContainer).name))
3840 found = 1;
3841 else
3842 iContainer = iContainer + 1;
3843 end
3844 end
3845 % If container is found : return it
3846 if (found)
3847 argout1 = bst_GUI.panelContainers(iContainer).jHandle;
3848 else
3849 % warning('Brainstorm:InvalidContainer', 'Container ''%s'' could not be found.', ContainerName);
3850 end
3851
3852
3853 %% ==== PANELS ====
3854 case 'Panel'
3855 % Get Brainstorm GUI context structure
3856 if (isempty(GlobalData) || isempty(GlobalData.Program.GUI) || ~isfield(GlobalData.Program.GUI, 'panels'))
3857 return
3858 end
3859 listPanels = GlobalData.Program.GUI.panels;
3860 % Get Panel in argument
3861 if ((nargin >= 2) && (ischar(varargin{2})))
3862 PanelName = varargin{2};
3863 % If no panel name in argument : just display all the panels names
3864 else
3865 disp('Registered panels :');
3866 for iContainer = 1:length(listPanels)
3867 disp([' - ' get(listPanels(iContainer), 'name')]);
3868 end
3869 return
3870 end
3871 % Look for panelName in all the registered panels
3872 iPanel = find(strcmpi(PanelName, get(listPanels, 'name')), 1);
3873 if ~isempty(iPanel)
3874 argout1 = listPanels(iPanel);
3875 argout2 = iPanel;
3876 end
3877
3878
3879 %% ==== PANEL CONTROLS ====
3880 % Calls : bst_get('PanelControls', PanelName)
3881 case 'PanelControls'
3882 % Get Panel name in argument
3883 if ((nargin >= 2) && (ischar(varargin{2})))
3884 PanelName = varargin{2};
3885 else
3886 error('Invalid call to bst_get()');
3887 end
3888 % Find BstPanel with this name
3889 bstPanel = bst_get('Panel', PanelName);
3890 % If panel was found : return its controls
3891 if ~isempty(bstPanel)
3892 argout1 = get(bstPanel, 'sControls');
3893 end
3894
3895 %% ===== NODES COPY =====
3896 % Calls : bst_get('Clipboard')
3897 case 'Clipboard'
3898 argout1 = GlobalData.Program.Clipboard.Nodes;
3899 argout2 = GlobalData.Program.Clipboard.isCut;
3900
3901 %% ==== DIRECTORIES ====
3902 case 'DirDefaultSubject'
3903 argout1 = '@default_subject';
3904 case 'DirDefaultStudy'
3905 argout1 = '@default_study';
3906 case 'DirAnalysisIntra'
3907 argout1 = '@intra';
3908 case 'DirAnalysisInter'
3909 argout1 = '@inter';
3910 case 'NormalizedSubjectName'
3911 argout1 = 'Group_analysis';
3912
3913 %% ==== OTHER ====
3914 case 'ResizeFunction'
3915 if (bst_get('MatlabVersion') <= 803)
3916 argout1 = 'ResizeFcn';
3917 else
3918 argout1 = 'SizeChangedFcn';
3919 end
3920 case 'groot'
3921 if (bst_get('MatlabVersion') <= 803)
3922 argout1 = 0;
3923 else
3924 argout1 = groot;
3925 end
3926 case 'JFrame'
3927 hFig = varargin{2};
3928 MatlabVersion = bst_get('MatlabVersion');
3929 jFrame = [];
3930 try
3931 if (MatlabVersion <= 705)
3932 jf = get(hFig, 'javaframe');
3933 jFrame = jf.fFigureClient.getWindow();
3934 elseif (MatlabVersion <= 712)
3935 jf = get(handle(hFig), 'javaframe');
3936 jFrame = jf.fFigureClient.getWindow();
3937 elseif (MatlabVersion <= 803)
3938 jf = get(handle(hFig), 'javaframe');
3939 jFrame = jf.fHG1Client.getWindow();
3940 elseif (MatlabVersion < 907) % Matlab >= 2019b deprecated the JavaFrame property
3941 warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
3942 jf = get(hFig, 'javaframe');
3943 warning('on', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
3944 jFrame = jf.fHG2Client.getWindow();
3945 else
3946 disp('BST> Error: Matlab 2019b deprecated the JavaFrame property.');
3947 end
3948 catch
3949 disp('BST> Warning: Cannot get the JavaFrame property for the selected figure.');
3950 end
3951 argout1 = jFrame;
3952
3953 %% ==== ERROR ====
3954 otherwise
3955 error(sprintf('Invalid context : "%s"', contextName));
3956 end
3957 end
3958
3959
3960
3961
3962 %% ==== HELPERS ====
3963 % Return all the protocol studies that have a given file in its structures
3964 % Possible field names: Result.DataFile, Result.FileName, Data.FileName, Channel.FileName
3965 %
3966 % USAGE: [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile, iStudiesList)
3967 % [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile)
3968 function [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile, iStudiesList)
3969 global GlobalData;
3970 sFoundStudy = [];
3971 iFoundStudy = [];
3972 iItem = [];
3973 % If no file provided, return
3974 if isempty(fieldFile)
3975 return;
3976 end
3977 % Extract folder(s) of the file(s) we're looking for
3978 fieldParts = strfind(fieldFile, '|');
3979 if ~isempty(fieldParts)
3980 fieldParts(end+1) = length(fieldFile);
3981 fieldFolders = {};
3982 iLast = 1;
3983 for iPart = 1:length(fieldParts)
3984 folder = fileparts(fieldFile(iLast:fieldParts(iPart)-1));
3985 if ~isempty(folder)
3986 fieldFolders{end + 1} = folder;
3987 end
3988 iLast = fieldParts(iPart) + 1;
3989 end
3990 else
3991 fieldFolders = {fileparts(fieldFile)};
3992 end
3993 % Get protocol information
3994 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
3995 % List studies to process
3996 if (nargin < 4) || isempty(iStudiesList)
3997 iStudiesList = [-2, -3, 1:length(ProtocolStudies.Study)];
3998 end
3999
4000 % NORMAL STUDIES: Look for surface file in all the surfaces of all subjects
4001 for iStudy = iStudiesList
4002 % Get study
4003 switch (iStudy)
4004 case -2, sStudy = ProtocolStudies.AnalysisStudy;
4005 case -3, sStudy = ProtocolStudies.DefaultStudy;
4006 otherwise, sStudy = ProtocolStudies.Study(iStudy);
4007 end
4008 % Check if field is available for the study
4009 if isempty(sStudy.(fieldGroup))
4010 continue;
4011 end
4012 % Check we are in the correct folder
4013 if ~any(file_compare(fieldFolders, fileparts(sStudy.FileName)))
4014 continue;
4015 end
4016 % Get list of files from study
4017 filesList = {sStudy.(fieldGroup).(fieldName)};
4018 if isempty(filesList)
4019 continue;
4020 end
4021 % Replace empty cells with empty strings
4022 iValidFiles = find(cellfun(@ischar, filesList));
4023 if isempty(iValidFiles)
4024 continue;
4025 end
4026 % Find target in this list
4027 iItem = find(file_compare(filesList(iValidFiles), fieldFile));
4028 if ~isempty(iItem)
4029 sFoundStudy = sStudy;
4030 iFoundStudy = iStudy;
4031 iItem = iValidFiles(iItem);
4032 return
4033 end
4034 end
4035 end
4036
4037
4038 %% ===== FILL MISSING FIELDS =====
4039 function bstPref = FillMissingFields(PrefName, defPref)
4040 global GlobalData;
4041 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, PrefName)
4042 bstPref = GlobalData.Preferences.(PrefName);
4043 bstPref = struct_copy_fields(bstPref, defPref, 0);
4044 else
4045 bstPref = defPref;
4046 end
4047 end
4048
4049
4050
4051
4052
4053
4054
To change parameters or database structures: bst_set.m.
1 function bst_set( varargin )
2 % BST_SET: Set a Brainstorm structure.
3 %
4 % DESCRIPTION: This function is used to abstract the way that these structures are stored.
5 %
6 % USAGE:
7 % ====== DIRECTORIES ==================================================================
8 % - bst_set('BrainstormHomeDir', BrainstormHomeDir)
9 % - bst_set('BrainstormTmpDir', BrainstormTmpDir)
10 % - bst_set('BrainstormDbDir', BrainstormDbDir)
11 % - bst_set('LastUsedDirs', sDirectories)
12 % - bst_set('BrainSuiteDir', BrainSuiteDir)
13 % - bst_set('PythonExe', PythonExe)
14 % - bst_set('PluginCustomPath', PluginCustomPath)
15 %
16 % ====== PROTOCOLS ====================================================================
17 % - bst_set('iProtocol', iProtocol)
18 % - bst_set('ProtocolInfo', sProtocolInfo)
19 % - bst_set('ProtocolSubjects', ProtocolSubjects)
20 % - bst_set('isProtocolLoaded', isProtocolLoaded)
21 % - bst_set('isProtocolModified',isProtocolModified)
22 % - bst_set('ProtocolStudies', ProtocolStudies)
23 % - bst_set('Study', iStudy, sStudy) : Set a study in current protocol
24 % - bst_set('Subject', iSubject, sSubject) : Set a subject in current protocol
25 %
26 % ====== GUI =================================================================
27 % - bst_set('Layout', sLayout)
28 % - bst_set('Layout', PropName, PropValue)
29 % - bst_set('Clipboard', Nodes, isCut) : Copy operation from the tree
30 %
31 % ====== CONFIGURATION =================================================================
32 % - bst_set('Version', Version)
33 % - bst_set('ByteOrder', value) : 'b' for big endian, 'l' for little endian
34 % - bst_set('AutoUpdates', isAutoUpdates)
35 % - bst_set('ExpertMode', isExpertMode)
36 % - bst_set('DisplayGFP', isDisplayGFP)
37 % - bst_set('DownsampleTimeSeries', isDownsampleTimeSeries)
38 % - bst_set('GraphicsSmoothing', isGraphicsSmoothing)
39 % - bst_set('ForceMatCompression', isForceCompression)
40 % - bst_set('IgnoreMemoryWarnings', isIgnoreMemoryWarnings)
41 % - bst_set('SystemCopy', isSystemCopy)
42 % - bst_set('DisableOpenGL', isDisableOpenGL)
43 % - bst_set('InterfaceScaling', InterfaceScaling)
44 % - bst_set('TSDisplayMode', TSDisplayMode) : {'butterfly','column'}
45 % - bst_set('ElectrodeConfig', ElectrodeConfig, Modality)
46 % - bst_set('DefaultFormats' defaultFormats)
47 % - bst_set('BFSProperties', [scalpCond,skullCond,brainCond,scalpThick,skullThick])
48 % - bst_set('ImportEegRawOptions', ImportEegRawOptions)
49 % - bst_set('BugReportOptions', BugReportOptions)
50 % - bst_set('DefaultSurfaceDisplay', displayStruct)
51 % - bst_set('MagneticExtrapOptions', extrapStruct)
52 % - bst_set('TimefreqOptions_morlet', Options)
53 % - bst_set('TimefreqOptions_fft', Options)
54 % - bst_set('TimefreqOptions_psd', Options)
55 % - bst_set('TimefreqOptions_hilbert', Options)
56 % - bst_set('TimefreqOptions_plv', Options)
57 % - bst_set('OpenMEEGOptions', Options)
58 % - bst_set('DuneuroOptions', Options)
59 % - bst_set('GridOptions_headmodel', Options)
60 % - bst_set('GridOptions_dipfit', Options)
61 % - bst_set('UniformizeTimeSeriesScales', isUniform)
62 % - bst_set('FlipYAxis', isFlipY)
63 % - bst_set('AutoScaleY', isAutoScaleY)
64 % - bst_set('FixedScaleY', Modality, Value)
65 % - bst_set('XScale', XScale)
66 % - bst_set('YScale', YScale)
67 % - bst_set('ShowXGrid', isShowXGrid)
68 % - bst_set('ShowYGrid', isShowYGrid)
69 % - bst_set('ShowZeroLines', isShowZeroLines)
70 % - bst_set('ShowEventsMode', ShowEventsMode)
71 % - bst_set('Resolution', [resX,resY])
72 % - bst_set('UseSigProcToolbox', UseSigProcToolbox)
73 % - bst_set('RawViewerOptions', RawViewerOptions)
74 % - bst_set('TopoLayoutOptions', TopoLayoutOptions)
75 % - bst_set('StatThreshOptions', StatThreshOptions)
76 % - bst_set('ContactSheetOptions', ContactSheetOptions)
77 % - bst_set('ProcessOptions', ProcessOptions)
78 % - bst_set('MriOptions', MriOptions)
79 % - bst_set('CustomColormaps', CustomColormaps)
80 % - bst_set('DigitizeOptions', DigitizeOptions)
81 % - bst_set('ReadOnly', ReadOnly)
82 % - bst_set('LastPsdDisplayFunction', LastPsdDisplayFunction)
83 % - bst_set('PlotlyCredentials', Username, ApiKey, Domain)
84 % - bst_set('KlustersExecutable', ExecutablePath)
85 % - bst_set('ExportBidsOptions'), ExportBidsOptions)
86 %
87 % SEE ALSO bst_get
88
89 % @=============================================================================
90 % This function is part of the Brainstorm software:
91 % https://neuroimage.usc.edu/brainstorm
92 %
93 % Copyright (c)2000-2020 University of Southern California & McGill University
94 % This software is distributed under the terms of the GNU General Public License
95 % as published by the Free Software Foundation. Further details on the GPLv3
96 % license can be found at http://www.gnu.org/copyleft/gpl.html.
97 %
98 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
99 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
100 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
101 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
102 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
103 %
104 % For more information type "brainstorm license" at command prompt.
105 % =============================================================================@
106 %
107 % Authors: Francois Tadel, 2008-2021
108 % Martin Cousineau, 2017
109
110 global GlobalData;
111
112 %% ==== PARSE INPUTS ====
113 if ((nargin >= 1) && ischar(varargin{1}))
114 contextName = varargin{1};
115 if (nargin >= 2)
116 contextValue = varargin{2};
117 else
118 contextValue = [];
119 end
120 else
121 error('Usage : bst_set(contextName, contextValue)');
122 end
123
124 % Get required context structure
125 switch contextName
126 %% ==== BRAINSTORM CONFIGURATION ====
127 case 'Version'
128 GlobalData.Program.Version = contextValue;
129 case 'BrainstormHomeDir'
130 GlobalData.Program.BrainstormHomeDir = contextValue;
131 case 'BrainstormDbDir'
132 GlobalData.DataBase.BrainstormDbDir = contextValue;
133 case 'BrainstormTmpDir'
134 GlobalData.Preferences.BrainstormTmpDir = contextValue;
135
136 %% ==== PROTOCOL ====
137 case 'iProtocol'
138 if isnumeric(contextValue)
139 GlobalData.DataBase.iProtocol = contextValue;
140 else
141 error('iProtocol should be a number.');
142 end
143 case {'ProtocolSubjects', 'ProtocolStudies'}
144 for structField = fieldnames(contextValue)'
145 GlobalData.DataBase.(contextName)(GlobalData.DataBase.iProtocol).(structField{1}) = contextValue.(structField{1});
146 end
147 GlobalData.DataBase.isProtocolModified(GlobalData.DataBase.iProtocol) = 1;
148 case 'ProtocolInfo'
149 for structField = fieldnames(contextValue)'
150 GlobalData.DataBase.(contextName)(GlobalData.DataBase.iProtocol).(structField{1}) = contextValue.(structField{1});
151 end
152 case 'isProtocolLoaded'
153 GlobalData.DataBase.isProtocolLoaded(GlobalData.DataBase.iProtocol) = contextValue;
154 case 'isProtocolModified'
155 GlobalData.DataBase.isProtocolModified(GlobalData.DataBase.iProtocol) = contextValue;
156
157 %% ==== SUBJECT ====
158 case 'Subject'
159 % Get subjects list
160 ProtocolSubjects = bst_get('ProtocolSubjects');
161 iSubject = varargin{2};
162 sSubject = varargin{3};
163 % If default subject
164 if (iSubject == 0)
165 ProtocolSubjects.DefaultSubject = sSubject;
166 else
167 ProtocolSubjects.Subject(iSubject) = sSubject;
168 end
169 % Update DataBase
170 bst_set('ProtocolSubjects', ProtocolSubjects);
171
172
173 %% ==== STUDY ====
174 case 'Study'
175 % Get studies list
176 ProtocolStudies = bst_get('ProtocolStudies');
177 iStudies = varargin{2};
178 sStudies = varargin{3};
179 iAnalysisStudy = -2;
180 iDefaultStudy = -3;
181 for i = 1:length(iStudies)
182 % Normal study
183 if (iStudies(i) > 0)
184 ProtocolStudies.Study(iStudies(i)) = sStudies(i);
185 % Inter-subject analysis study
186 elseif (iStudies(i) == iAnalysisStudy)
187 ProtocolStudies.AnalysisStudy = sStudies(i);
188 % Default study
189 elseif (iStudies(i) == iDefaultStudy)
190 ProtocolStudies.DefaultStudy = sStudies(i);
191 end
192 end
193 % Update DataBase
194 bst_set('ProtocolStudies', ProtocolStudies);
195
196
197 %% ==== GUI ====
198 % USAGE: bst_set('Layout', sLayout)
199 % bst_set('Layout', PropName, PropValue)
200 case 'Layout'
201 if (nargin == 2) && isstruct(contextValue)
202 GlobalData.Preferences.Layout = contextValue;
203 isUpdateScreens = 0;
204 elseif (nargin == 3) && ischar(contextValue) && isfield(GlobalData.Preferences, 'Layout') && isfield(GlobalData.Preferences.Layout, contextValue)
205 GlobalData.Preferences.Layout.(contextValue) = varargin{3};
206 isUpdateScreens = strcmpi(contextValue, 'DoubleScreen');
207 else
208 error('Invalid call to bst_set.');
209 end
210 % Update screen configuration
211 GlobalData.Program.ScreenDef = gui_layout('GetScreenClientArea');
212 % Update layout right now
213 gui_layout('Update');
214 % If the number of screen was changed: update the maximum size of the Brainstorm window
215 if isUpdateScreens
216 gui_layout('UpdateMaxBstSize');
217 end
218
219 % USAGE: bst_set('FixedScaleY', [])
220 % bst_set('FixedScaleY', Modality, Value)
221 case 'FixedScaleY'
222 if (nargin == 3) && ~isempty(contextValue) && ~isempty(varargin{3})
223 GlobalData.Preferences.FixedScaleY.(contextValue) = varargin{3};
224 elseif (nargin == 2) && isempty(contextValue)
225 GlobalData.Preferences.FixedScaleY = struct();
226 end
227
228 case 'ByteOrder'
229 switch(contextValue)
230 case {'b','ieee-le','n'}
231 GlobalData.Preferences.ByteOrder = 'b';
232 case {'l','ieee-be'}
233 GlobalData.Preferences.ByteOrder = 'l';
234 otherwise
235 error('Invalid byte order.');
236 end
237
238 case 'Clipboard'
239 if (length(varargin) >= 3)
240 isCut = varargin{3};
241 else
242 isCut = 0;
243 end
244 GlobalData.Program.Clipboard.Nodes = contextValue;
245 GlobalData.Program.Clipboard.isCut = isCut;
246
247 case 'ElectrodeConfig'
248 Modality = varargin{2};
249 ElectrodeConf = varargin{3};
250 if ~ismember(Modality, {'EEG','SEEG','ECOG'})
251 error(['Invalid modality: ' Modality]);
252 end
253 GlobalData.Preferences.(contextName).(Modality) = ElectrodeConf;
254
255 case {'UniformizeTimeSeriesScales', 'XScale', 'YScale', 'FlipYAxis', 'AutoScaleY', 'ShowXGrid', 'ShowYGrid', 'ShowZeroLines', 'ShowEventsMode', ...
256 'Resolution', 'AutoUpdates', 'ExpertMode', 'DisplayGFP', 'ForceMatCompression', 'GraphicsSmoothing', 'DownsampleTimeSeries', ...
257 'DisableOpenGL', 'InterfaceScaling', 'TSDisplayMode', 'UseSigProcToolbox', 'LastUsedDirs', 'DefaultFormats', ...
258 'BFSProperties', 'ImportDataOptions', 'ImportEegRawOptions', 'RawViewerOptions', 'MontageOptions', 'TopoLayoutOptions', ...
259 'StatThreshOptions', 'ContactSheetOptions', 'ProcessOptions', 'BugReportOptions', 'DefaultSurfaceDisplay', ...
260 'MagneticExtrapOptions', 'MriOptions', 'NodelistOptions', 'IgnoreMemoryWarnings', 'SystemCopy', ...
261 'TimefreqOptions_morlet', 'TimefreqOptions_hilbert', 'TimefreqOptions_fft', 'TimefreqOptions_psd', 'TimefreqOptions_plv', ...
262 'OpenMEEGOptions', 'DuneuroOptions', 'DigitizeOptions', 'CustomColormaps', 'PluginCustomPath', 'BrainSuiteDir', 'PythonExe', ...
263 'GridOptions_headmodel', 'GridOptions_dipfit', 'LastPsdDisplayFunction', 'KlustersExecutable', 'ExportBidsOptions'}
264 GlobalData.Preferences.(contextName) = contextValue;
265
266 case 'ReadOnly'
267 GlobalData.DataBase.isReadOnly = contextValue;
268
269 case 'PlotlyCredentials'
270 if length(varargin) ~= 4
271 error('Invalid call to bst_set.');
272 end
273 [username, apiKey, domain] = varargin{2:4};
274
275 if isempty(domain)
276 % Default Plot.ly server
277 domain = 'http://plot.ly';
278 end
279
280 % Plotly needs a URL with HTTP and no trailing slash.
281 if strfind(domain, 'https://')
282 domain = strrep(domain, 'https://', 'http://');
283 elseif isempty(strfind(domain, 'http://'))
284 domain = ['http://', domain];
285 end
286 if domain(end) == '/'
287 domain = domain(1:end-1);
288 end
289
290 saveplotlycredentials(username, apiKey);
291 saveplotlyconfig(domain);
292
293 %% ==== ERROR ====
294 otherwise
295 error('Invalid context : ''%s''', contextName);
296
297
298 end
299
300
301
302
File structures
The structures of the different types of files were described in the sections "On the hard drive" of the introduction tutorials. Here is a summary of all these sections:
Continuous recordings: File type "raw", Event markers.
Scouts and atlases: Saved in the surface files, Scouts.
Custom processing
In many situations, you will find useful to read the files available in the database, and maybe modify them. The easiest approaches do not require any scripting, we will start by reviewing them quickly.
Process: Run Matlab command
If you want to modify the values saved in a file (eg. the field "F" from a "data" file), the easiest way is probably to use the process1 File > Run Matlab command. It is also available from Process2 in the category "Other".
It loads the files in input and run them through a piece of Matlab code that you can edit freely. It can extend a lot the flexibility of the Brainstorm pipeline manager, providing an easy access to any Matlab function or script.
DataMat is the exact content of the corresponding .mat file, as loaded with Matlab's load() function. Edit some of the fields of this structure from the Matlab command window:
Now right-click on the folder containing the original file > File > Import from Matlab > DataMat:
If instead, you right-click on the original file and select the menu File > Import from Matlab, it overwrites the selected file instead of creating a new one with the selected structure.
Reference: File manipulation
Useful functions for manipulating file names and paths (read the code of the functions for help):
file_fullpath: Converts a relative file path to an absolute path.
file_short: Converts an absolute file path to a short path, relative to the current protocol folder.
file_gettype: Returns the type of a file.
Reading files from a script (all the functions take relative paths in input):
in_tess_bst(TessFile): Read a surface file.
in_mri_bst(MriFile): Read a MRI/volume file.
in_bst_data(DataFile): Read an imported epoch.
in_bst_timefreq(TimefreqFile): Read a power spectrum, time-frequency or connectivity file.
in_bst_channel(ChannelFile): Read a channel file.
in_bst_headmodel(HeadmodelFile, ApplyOrient): Read a head model file and apply orientations.
in_bst_results(ResultsFile, LoadFull): Load a source file and optionally reconstruct the full source time series on the fly (ImagingKernel * recordings).
in_bst_matrix(MatrixFile): Read a file with the type "matrix".
in_bst(FileName, TimeWindow): Read any Brainstorm data file with the possibility to load only a specific part of the file. "TimeWindow" is a range of time values in seconds: [tStart, tStop].
bst_process('LoadInputFile', FileName, Target, TimeWindow): The most high-level function for reading data files. "Target" is a string with the list of signal names or types to load.
bst_memory('GetConnectMatrix', TimefreqMat): Rebuild a full connectivity matrix.
in_fopen(DataFile, FileFormat, ImportOptions): Low-level function for opening continuous files.
in_fread(sFile, ChannelMat, iEpoch, SamplesBounds, iChannels, ImportOptions): Low-level function for reading blocks from continuous files. Requires a call to in_fopen first to get the sFile structure.
Saving files:
bst_save(FileName, FileMat, Version, isAppend): Save a file but does not register it in the database.
FileName: Absolute path to a .mat file, use in combination with file_fullpath for relative paths.
FileMat: Valid Brainstorm structure, corresponding to the file type.
Version: Defines which version of the Matlab .mat format is used to store the data:
- 'v6': Fastest option, bigger files, no compression, no files >2Gb
- 'v7': Slower option, compressed, no files >2Gb
- 'v7.3': Much slower than the others, compressed, but only way to save files > 2Gb.
isAppend: If set to 1, updates only the fields defined in FileMat, keep the others untouched.
file_unique: Produces a unique file name by adding a number tag to it.
bst_process('GetNewFilename', OutputFolder, BaseFilename): Generate a new unique file name based on the beginning of the file name (eg. BaseFilename='data_average_test_').
Registering new files in the database:
db_add(iStudy/iSubject, FileMat): Add a new file in an anatomy folder or a functional data folder. This function saves the file and then reloads the folder. FileMat must be a structure, not a filename. You should not save the file manually before calling this function.
db_add_data(iStudy, FileName, FileMat): Register in the database a structure FileMat that has already been saved in file FileName. You should call bst_save manually before calling this function.
db_add_data(iStudy, FileName, FileMat, iItem): Overwrites the existing file #iItem.
Reload folders (if you saved or deleted files without registering correctly the modification in the database):
db_reload_studies(iStudies): Reload only the select data folders (aka "studies").
db_reload_conditions(iSubjects): Reload all the data folders for a subject.
db_reload_subjects(iSubjects): Reload the anatomy of the selected subjects.
db_reload_database('current'): Reload the entire protocol (anatomy and functional data).
Other useful database functions:
db_add_condition: Create a new folder in a subject.
db_add_subject: Create a new subject.
db_delete_studies: Delete a list of folders.
db_delete_subjects: Delete a list of subjects.
db_group_conditions: Merge two folders from the same subject.
db_rename_condition: Rename a folder.
db_rename_subject: Rename a subject.
db_set_channel: Set the channel file for a folder.
db_set_noisecov: Set the noise/data covariance for a folder, or copy to other folders/subjects.
db_set_template: Copy an anatomy template to a subject or use it as the default anatomy.
Export a file from the database to other file formats (read the comments in the functions for help):
export_channel
export_data
export_events
export_result
export_timefreq
export_matrix
export_mri
export_surfaces
export_protocol: Export a subject or an entire protocol as a .zip file.
Convert Brainstorm structures to FieldTrip structures:
out_fieldtrip_channel
out_fieldtrip_data
out_fieldtrip_timefreq
out_fieldtrip_headmodel
out_fieldtrip_results
out_fieldtrip_matrix
Reference: Display functions
Create new visualization figures:
view_channels: Display sensors in a 3D figure.
view_helmet: Display the inner surface of the MEG helmet in a 3D figure.
view_timeseries: Display a data file as time series.
view_timeseries_matrix: Display a custom matrix as time series.
view_topography: Display a data file as a spatial topography.
view_erpimage: Display multiple data files as an image, signal by signal.
view_timefreq: Open a time-frequency file (various display modes available).
view_spectrum: Display a power spectrum (PSD or time-frequency files).
view_connect: Open a connectivity matrix (various display modes available).
view_matrix: Open a "matrix" file (various display modes available).
view_contactsheet: Create a contact sheet in time or across a volume from an existing figure.
view_noisecov: Display a noise or data covariance file.
view_dipoles: Open a dipoles file (various display modes available).
view_pac: Open PAC results (various display modes available).
view_mri: View a MRI file in the MRI viewer (with or without a functional overlay from a source file).
view_mri_3d: View a MRI file in a 3D figure (with or without a functional overlay from a source file).
view_surface: View a surface.
view_surface_data: View a surface file with a source file as its texture.
panel_montage('SetCurrentMontage', hFig, MontageName): Change the montage of channels.
bst_figures('SetSelectedRows', SelectedChannels): Set selected channels (cell array of strings).
figure_timeseries('SetTimeSelectionManual', hFig, TimeWindow): Select a time segment.
Configure 3D figures:
figure_3d('SetStandardView', hFig, 'left'): Change camera view (top,bottom,left,right,front,back).
figure_3d('ViewSensors', hFig, isMarkers, isLabels): Enable the view of sensor markers and labels.
panel_surface('SetShowSulci', hFig, iTess, 1): Show/hide the sulci (darker color for deeper areas).
panel_surface('SetSurfaceColor', hFig, iTess, [1 0 0]): Set the surface color.
panel_surface('SetSurfaceSmooth', hFig, iTess, Smooth, 0): Set the amount of smoothing (0-1).
panel_surface('SetSurfaceTransparency', hFig, iTess, Transp): Set the surface transparency (0-1).
panel_surface('SetDataThreshold', hFig, iTess, Thresh): Set the amplitude threshold.
panel_surface('SetSizeThreshold', hFig, iTess, MinSize): Set size threshold (min size slider).
panel_surface('SelectHemispheres', target): Equivalent to clicking on the buttons in the Resect panel of the Surface tab. Possible target values: 'left', 'right', 'struct', 'none'
bst_colormaps('SetMaxMode', ColormapType, MaxMode): Colorbar range ('global', 'local', 'custom').
bst_colormaps('SetMaxCustom', ColormapType, [], Min, Max): Set a custom colorbar range.
bst_colormaps('SetColormapAbsolute', ColormapType, isAbsolute): Show positive or relative values
bst_colormaps('SetDisplayColorbar', ColormapType, isDisplay): Show colorbar in the figures.
bst_colormaps('RestoreDefaults', ColormapType): Restore the default configuration for a colormap.
ColormapType: anatomy, meg, eeg, sources, stat1, stat2, time, timefreq, connect1, connectn, image
Configure statistical thresholding:
StatThreshOptions = bst_get('StatThreshOptions'): Get display options selected in the Stat tab.
bst_set('StatThreshOptions', StatThreshOptions): Change the options selected in the Stat tab.
StatThreshOptions.pThreshold: Current significance level α (ie. p-value threshold)
StatThreshOptions.Correction: Correction for multiple comparisons ('none', 'fdr', 'bonferroni')
StatThreshOptions.Control: List of dimensions to correct for multiple comparisons (default = [1 2 3])
Export the contents of a figure to a file:
out_figure_image: Screen capture of any Brainstorm figure.
out_figure_movie: Save a movie from one or multiple Brainstorm figures.
out_figure_timefreq: Extract some of the data displayed in a time-frequency figure.
out_figure_timeseries: Extract some of the data displayed in a time series figure.
Example: Creating a new file
This section illustrates how to add new files to the database. We will create a sinusoidal signal and save it in a "matrix" file, in a new folder of the subject "Test".
% Time: 1 second with a sampling frequency of 1000Hz
t = 0:0.001:1;
% Generate two sinsuoidal signals (20Hz,30Hz)
F = [sin(20*2*pi*t); 0.5*sin(30*2*pi*t)];
% Initialize an empty "matrix" structure
sMat = db_template('matrixmat');
% Fill the required fields of the structure
sMat.Value = F;
sMat.Comment = 'Test sinusoids';
sMat.Description = {'Signal #1: 20Hz'; 'Signal #2: 30Hz'};
sMat.Time = t;
% Create a new folder "Script" in subject "Test"
iStudy = db_add_condition('Test', 'Script');
% Get the corresponding study structure
sStudy = bst_get('Study', iStudy);
There are many options to add a new file to the database, with various levels of requirements. You can call the db_add function (reloads the destination folder, therefore slow if you save many files), save the file in the corresponding folder and reload the protocol (slow as well), or register the file in the database manually (more complicated but faster).
Option #1: db_add
OutputFile = db_add(iStudy, sMat);
Option #2: bst_save / db_reload_studies
% Get the full path to the new folder
% (same folder as the brainstormstudy.mat file for this study)
OutputFolder = bst_fileparts(file_fullpath(sStudy.FileName));
% Get a new unique filename (including a timestamp)
MatrixFile = bst_process('GetNewFilename', OutputFolder, 'matrix_test');
% Save file
bst_save(MatrixFile, sMat, 'v6');
% Reload the folder in which the new file was saved
db_reload_studies(iStudy);
Option #3: bst_save / db_add_data
% Another way to generate a unique filename (without a timestamp)
MatrixFile = file_unique(bst_fullfile(OutputFolder, 'matrix_test.mat'));
% Save file
bst_save(MatrixFile, sMat, 'v6');
% Reference saved file in the database
db_add_data(iStudy, MatrixFile, sMat);
% Update the database explorer display
panel_protocols('UpdateNode', 'Study', iStudy);
Example: Editing events
A step that commonly requires manual changes is the definition of the event markers. For example, we have to combine external triggers or behavioral information with the existing events. This example illustrates how to load the events, modify them and save them back.
For the continuous recordings, the events are saved in the .mat file corresponding to the "Link to raw file". These structures contain only meta-data and information created with Brainstorm, the EEG/MEG recordings are available in a separate binary file. First, we need to load this link.
% Right-click on a "Link to raw file" in the database explorer
% > File > Copy file path to clipboard
RawFile = '/.../@rawS01.../data_0raw_S01_..._01_600Hz_notch.mat'
% Load the "sFile" structure, contained in the .F structure
% of the link file (data_0raw...mat)
sRaw = in_bst_data(RawFile, 'F');
>> sRaw.F.events
ans =
1x7 struct array with fields:
label
color
epochs
times
reactTimes
select
channels
notes
For example, let's say we want to add 30ms to all the events in the category "button" in order to compensate for some hardware delay, and create a new event category with the modified timing. We need first to identify what is the index of the category "button", in this array of 7 event structures.
% Find the index of the event category "button"
iEvtButton = find(strcmpi({sRaw.F.events.label}, 'button'));
>> iEvtButton
iEvtButton =
3
In the code above, note this special Matlab syntax that allows the concatenation of the values of one field across multiple structures, in an array of structures:
If you want to search instead all the events containing a specific tag, for example "bad", you can use the cellfun function (applies the same function sequentially to all the elements in a cell array and concatenates the results) in combination with the strfind function (search for a substring). The final call to the find function returns at which indices the list of tags found in the event label is not empty.
The code below copies the existing event category "button", renames it and add a 30ms offset. If you add or remove events, you must adjust the size of the other fields: epochs (always 1 for most file formats), channels and notes (cell array of empty matrices in most cases).
% Copy the event category "button" to a new category
iEvtNew = length(sRaw.F.events) + 1;
sRaw.F.events(iEvtNew) = sRaw.F.events(iEvtButton);
% Rename the new event to "button_offset"
sRaw.F.events(iEvtNew).label = 'button_offset';
% How many samples in 30ms (0.030s * 600Hz = 18 samples)
offsetSample = round(0.030 .* sRaw.F.prop.sfreq);
% Apply offset to the events in the "button_offset" category
sRaw.F.events(iEvtNew).times = sRaw.F.events(iEvtNew).times + 0.03
% Round new time values to the nearest sample
sRaw.F.events(iEvtNew).times = ...
round(sRaw.F.events(iEvtNew).times .* sRaw.F.prop.sfreq) ./ sRaw.F.prop.sfreq;
% Re-generate an epochs field with only ones, and empty notes and channels fields
% (optional here, as we didn't change the number of evt)
nTimes = size(sRaw.F.events(iEvtNew).times, 2);
sRaw.F.events(iEvtNew).epochs = ones(1, nTimes);
sRaw.F.events(iEvtNew).channels = cell(1, nTimes);
sRaw.F.events(iEvtNew).notes = cell(1, nTimes);
% Change the event color to yellow (red=1, green=1, blue=0)
sRaw.F.events(iEvtNew).color = [1 1 0];
>> sRaw.F.events(iEvtNew)
ans =
label: 'button_offset'
color: [1 1 0]
epochs: [1x40 double]
times: [1x40 double]
reactTimes: []
select: 1
channels: {1x40 cell}
notes: {1x40 cell}
The last step is to save the modifications back to the "Link to raw file". Here the call to file_fullpath is optional because the variable RawFile already contains the absolute path to the file.
% Update the sRaw structure to the RawFile file (the last parameter appends to the existing struct)
bst_save(file_fullpath(RawFile), sRaw, 'v6', 1);
Open the recordings to make sure your transformation worked the way you expected.
Find examples in the code
The easier way to understand how to use a function is to search the code with the "Find files" interface in Matlab. Go to the brainstorm3 folder, click on "Find files" (or Ctrl+Shift+F), enter the name of a function in "Find files containing text", Include subfolders, Match case. It will return all the lines that include the string you entered across all the files in the Brainstorm distribution. Just double-click on a line to jump to the code in the Matlab editor.
You can use the same interface to find what function is called when you click on a button or menu in the interface. Search for the label or the tooltip of the interface element in the same way. The example below shows how to track what happens when you click on the headmodel popup menu "Check spheres".
If you have trouble understanding how to set some input parameters, you can use the debugger to explore a real use case. Place a breakpoint at the begging of your function of interest (watch this tutorial if you don't know how to do this), for example in view_timeseries.m. Then click on the corresponding menus in the Brainstorm interface (eg. double-click on a data file). When the execution reaches the line you selected, it stops and gives you back the commands. You can explore the values in all the variables, modify them, and execute the code step by step (many options available in the Editor tab of Matlab).
Additional quality control
You can add in the reports all the information that may help you control the quality of the analysis, or figures you want to include in publications or clinical reports. The process "File > Save snapshot" lets you save some predefined views, but you can also custom screen captures. The example below shows how to add a "raster plot" for all the deviant trials from Run#01 in the report.
% Get all the deviant trials in Run#01 (the list includes the deviant average)
sDeviant = bst_process('CallProcess', 'process_select_files_data', [], [], ...
'subjectname', 'Subject01', ...
'condition', 'S01_AEF_20131218_01_600Hz_notch', ...
'tag', 'deviant');
% Open raster plot
hFig = view_erpimage({sDeviant.FileName}, 'erpimage', 'MEG');
% Select the channel MRT34
sOptions = panel_display('GetDisplayOptions');
sOptions.RowName = 'MRT34';
panel_display('SetDisplayOptions', sOptions);
% Screen capture of this figure
% bst_report('Snapshot', hFig, FileName, Comment, WindowPosition);
bst_report('Snapshot', hFig, [], 'ERP image: MRT34', [300 100 600 400]);
% Close figure
close(hFig);
You can also add messages in the reports (information, warning or errors).
% Function call: bst_report(MsgType, sProcess, sInputs, Message)
bst_report('Info', [], sDeviant, 'This is an information message.');
bst_report('Warning', [], sDeviant, 'This is a warning.');
bst_report('Error', [], sDeviant, 'This is an error.');
% Open the report viewer to show the current report (not saved yet)
bst_report('Open', 'Current');
Report generated with the code above:
Loop over subjects
Creating loops is not supported yet by the script generator, but relatively easy to do from a script without knowing too much about Matlab programming. The example below shows how to create a loop over subjects to import their anatomy. The dataset used here is from the tutorial MEG visual: single subject.
With the Process1 box empty, select the process "Import > Import anatomy > Import anatomy folder" and generate a script. Simplify if using the guidelines presented in the previous sections:
Add a for loop around all the steps to repeat on each subject ("for" before, and "end" after the code), and replace the indices "1" with the loop variable:
% Loop on subjects
for iSubject = 1:length(SubjectNames)
% Process: Import anatomy folder
bst_process('CallProcess', 'process_import_anatomy', [], [], ...
'subjectname', SubjectNames{iSubject}, ...
'mrifile', {RawFiles{iSubject}, 'FreeSurfer'}, ...
'nvertices', 15000);
end
Loop over acquisition runs
If you have multiple subjects for which the anatomy is already imported, and multiple runs to process for each subject, you can add two nested for loops to link all the runs to the database in the same script. The dataset used here is from the tutorial MEG visual: single subject.
With the Process1 box empty, select the process "Import > Import recordings > Create link to raw file" and generate a script. Simplify if using the guidelines presented in the previous sections:
Add two for loops around the code to repeat on all the runs:
% Loop on subjects
for iSubject = 1:length(SubjectNames)
% Loop on runs for each subject
for iRun = 1:length(RawFiles{iSubject})
% Process: Create link to raw file
sFileRaw = bst_process('CallProcess', 'process_import_data_raw', [], [], ...
'subjectname', SubjectNames{iSubject}, ...
'datafile', {RawFiles{iSubjects}{iRun}, 'FIF'}, ...
'channelreplace', 0, ...
'channelalign', 0, ...
'evtmode', 'value');
end
end
How to process an entire study
This section proposes a standard workflow for processing a full group study with Brainstorm. It contains the same steps of analysis as the introduction tutorials, but separating what can be done automatically from what should be done manually. This workflow can be adapted to most ERP studies (stimulus-based).
Prototype: Start by processing one or two subjects completely interactively (exactly like in the introduction tutorials). Use the few pilot subjects that you have for your study to prototype the analysis pipeline and check manually all the intermediate stages. Take notes of what you're doing along the way, so that you can later write a script that reproduces the same operations.
Anatomical fiducials: Set NAS/LPA/RPA and compute the MNI transformation for each subject.
Segmentation: Run FreeSurfer/BrainSuite to get surfaces and atlases for all the subjects.
File > Batch MRI fiducials: This menu prompts for the selection of the fiducials for all the subjects and saves a file fiducials.m in each segmentation folder. You will not have to redo this even if you have to start over your analysis from the beginning.
Script: Write a loop that calls the process "Import anatomy folder" for all the subjects.
Alternatives: Create and import the subjects one by one and set the fiducials at the import time. Or use the default anatomy for all the subjects (or use warped templates).
Script #1: Pre-processing: Loop on the subjects and the acquisition runs.
Create link to raw files: Link the subject and noise recordings to the database.
Event markers: Read and group triggers from digital and analog channel, fix stimulation delays
Evaluation: Power spectrum density of the recordings to evaluate their quality.
Compute SSP: Heartbeats, Blinks (this selects the first component of each decomposition)
Compute ICA: If you have some artifacts you'd like to remove with ICA (no default selection).
Screenshots: Check the MRI/sensors registration, PSD before and after corrections, SSP.
Export the report: One report per subject, or one report for all the subjects, saved in HTML.
Manual inspection #1:
Check the reports: Information messages (number of events, errors and warnings) and screen captures (registration problems, obvious noisy channels, incorrect SSP topographies).
Mark bad channels: Open the recordings, select the channels and mark them as bad. Or use the process "Set bad channels" to mark the same bad channels in multiple files.
Fix the SSP/ICA: For the suspicious runs: Open the file, adjust the list of blink and cardiac events, remove and recompute the SSP decompositions, manually select the components.
Detect other artifacts: Run the process on all the runs of all the subjects at once (select all the files in Process1 and run the process, or generate the equivalent script).
Mark bad segments: Review the artifacts detected in 1-7Hz and 40-240Hz, keep only the ones you really want to remove, then mark the event categories as bad. Review quickly the rest of the file and check that there are no other important artifacts.
Additional SSP: If you find one type of artifact that repeats (typically saccades and SQUID jumps), you can create additional SSP projectors, either with the process "SSP: Generic" or directly from a topography figure (right-click on the figure > Snapshot> Use as SSP projector).
Importing: Process "Import MEG/EEG: Events" and "Pre-process > Remove DC offset".
Averaging: Average trials by run, average runs by subject (registration problem in MEG).
Noise covariance: Compute from empty room or resting recordings, copy to other folders.
Head model: Compute for each run, or compute once and copy if the runs are co-registered.
Sources: Compute for each run, average across runs and subjects in source space for MEG.
Time-frequency: Computation with Hilbert transform or Morlet wavelets, then normalize.
Screenshots: Check the quality of all the averages (time series, topographies, sources).
Export the report: One report per subject, or one report for all the subjects, saved in HTML.
Manual inspection #2:
Check the reports: Check the number of epochs imported and averaged in each condition, check the screen capture of the averages (all the primary responses should be clearly visible).
Regions of interest: If not using predefined regions from an atlas, define the scouts on the anatomy of each subject (or on the template and then project them to the subjects).
Script #3: Group analysis, ROI-based analysis, etc.
Averaging: Group averages for the sensor data, the sources and the time-frequency maps.
Statistics: Contrast between conditions or groups of subjects.
Regions of interest: Any operation that involve scouts.
Final scripts
The following script from the Brainstorm distribution reproduces the introduction tutorials ("Get started"): brainstorm3/toolbox/script/tutorial_introduction.m - Report: report_TutorialIntroduction.html
Matlab, including the toolboxes you need, needs to be installed on the server and a Brainstorm version needs to be located on the server. Start Brainstorm with the command "brainstorm server".
For the database: the folder "brainstorm_db" needs to be registered at the beginning of the script. You can either upload a protocol folder from your local computer, or create an empty brainstorm_db folder and a new protocol on the distance server. At the end of this initialization phase, you need to have something like the structure below:
/home/user/brainstorm3
/home/user/brainstorm_db/ProtocolName/anat
/home/user/brainstorm_db/ProtocolName/data
Your processing script could start with some of the elements below, depending on what you need:
% Start Brainstorm
cd /home/user/brainstorm3;
if ~brainstorm('status')
brainstorm server
end
% Path to a Brainstorm database (= a folder that contains one or more Brainstorm protocols)
BrainstormDbDir = '/home/user/brainstorm_db';
% Load a new uploaded database (sets BrainstormDbDir and load all the protocols it contains)
db_import(BrainstormDbDir);
% Alternative: Set the Brainstorm DB folder
% (defines where the new protocols are going to be created, but does not load anything)
bst_set('BrainstormDbDir', BrainstormDbDir);
% Get the protocol index of an existing protocol (already loaded previously in Brainstorm)
iProtocol = bst_get('Protocol', ProtocolName);
% Create a new protocol if needed
if isempty(iProtocol)
UseDefaultAnat = 0;
UseDefaultChannel = 0;
gui_brainstorm('CreateProtocol', ProtocolName, UseDefaultAnat, UseDefaultChannel);
end
% Delete an existing protocol
gui_brainstorm('DeleteProtocol', ProtocolName);
Execution: You should check that there is a Matlab license available on the server, and that RAM and disk quotas are large enough for the data you will create while processing. The Matlab version might differ from the version installed on your local computer or toolboxes might be missing, causing some errors.
A Brainstorm script can be executed either directly (it needs to start Brainstorm itself, like in the example script above), or started using the syntax brainstorm <script.m> <parameters> (starts Brainstorm in server mode, executes the script and quit Brainstorm). See section Starting Brainstorm.
Without Matlab
Brainstorm scripts can also be executed from the compiled version of Brainstorm, therefore not requiring a Matlab license, only the installation of the free MATLAB Runtime (see installation instructions, section "without Matlab"). Add the full path to the script and the parameters to the command line:
To avoid being asked for "brainstorm_db", add the argument: local Example: brainstorm3.command /usr/local/MATLAB/MATLAB_Runtime/v98 main.m local
In this configuration, Brainstorm is started using the command brainstorm server and then the script is executed. Therefore, your script should not start brainstorm again: remove the line "brainstorm server" from the example script in the section above.
Finding interface callback functions
If you are looking for the function called by a menu or a button in the interface:
In Matlab, go to the "brainstorm3" folder
Click on the button "Find file" in the ribbon "Editor" of Matlab interface (Ctrl+Shift+F)
Select the option "Include subfolders"
Search for the text of the menu or button you are looking for (eg. 'Set as default'); you can do a case-sensitive or a case-insensitive search (option "Match case")
It gives you the list of all the places where this text appears in the Brainstorm code. In the previous example, in tree_callbacks.m, you’d find a call to function SetDefaultSurf.
Double-click on the corresponding line to jump to the code
Right-click on "SetDefaultSurf" > Open "SetDefaultSurf"
The editor should jump to the code of function SetDefaultSurf(), and there you’d find your call to "db_surface_default"
Right-click on it > Open "db_surface_default" to open the function and read the header that should explain its usage (this example is not very detailed, sorry)
Sometimes it helps to look at other examples of calls to this function: Use the window "Find files" again to search for text "db_surface_default"