[TUTORIAL UNDER DEVELOPMENT: NOT READY FOR PUBLIC USE]
Authors: Francois Tadel, Elizabeth Bock, 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.
Requirements: You need a license for the Matlab environment in order to use these tools and execute custom scripts. If you are running the compiled version of Brainstorm with the MCR library, the only custom code you can run is through the menu File > Matlab console and the process "Run Matlab command".
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 on the 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 comment=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 "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, Mirror. 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 input 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 script would contain only one entry, but it written as a cell array so that it is easier to extend it to multiple subjects with a loop (described further in this tutorial).
% Start a new report
bst_report('Start', sFiles);
Start 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 explicitely 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, to call a subfunction available inside a .m file. This line above calls the function Report() in the file brainstorm3/toolbox/process/bst_report.m. This is made possible with the use of the short script "macro_methodcall" you will see at the top of many files. 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 files 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 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 contains the new files. If the process didn't create new files or was modifying exiting files, most of the time this variable would contain the same files as the input list.
Line by line: Footer
% Save and display report
ReportFile = bst_report('Save', sFiles);
Closes the current report and saves it in the user Brainstorm 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 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 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 wither 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
This 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 or change the inputs/outputs of a process. 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 a bit more specific.
Edit low-pass filter call: 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 in the script.
Edit the call to the snapshot process: Change the input to sAvgDataLow, and remove the output parameter (we are not expecting output from it).
bst_process('CallProcess', 'process_snapshot', sAvgDataLow, [], ...
'target', 5, ... % Recordings time series
'modality', 1); % MEG (All)
Replace the last lines with the following, 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 two 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 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
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).
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).
Graphic handles: Matlab graphic objects, name starting with a "h" (eg. hFig, hAxes, hLine, hText).
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, [], ...
'highpass', 0, ...
'lowpass', 30, ...
'sensortypes', 'MEG');
% 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 just 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 report_test.html that was saved somewhere on your computer.
On this page, you can get review everything that happened in the script: when it was executed, how long it took, what are the processes that were executed, some produced messages (two files were selected with the first process), and at the end you have 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 comment that includes "Avg: deviant". This is not the case anymore after the execution, because the low-pass filtered files also contain the same tags. 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 comment, 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 comments with tag: low
sAvgData = bst_process('CallProcess', 'process_select_tag', sAvgData, [], ...
'tag', 'low', ...
'search', 2, ... % Search the file comments
'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 comment 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 explicitely the output files your script generates if you need to fetch them later. You can use the process File > Add tag and File > Set comment.
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 explicitely start or restart Brainstorm.
brainstorm: Start Brainstorm with the regular GUI.
brainstorm nogui: Start in silent mode, without the GUI, without progress bar, without user interactions.
If you want to start Brainstorm only if Brainstorm 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);
The functions bst_get and bst_set allow you to query the database, access the configuration of the software and 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') % Returns the 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 currently displayed (0=no, 1=yes)
>> bst_set('FlipYAxis', 1) % The new figures will have the Y axis flipped
>> bst_set('TSDisplayMode', 'butterfly') % The new figures will use a "butterfly" view
>> bst_set('FieldTripDir', FieldTripDir) % Set the path where the FieldTrip toolbox is installed
To reference the files in the database, each protocol is subdivided in Subjects (the "anat" folder and 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, iTimefreq. You can see the indices in the database explorer by hovering your mouse over the nodes of the tree:
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 a study structure 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' % Corresponding subject filename
Condition: {'S01_AEF_20131218_01_600Hz_notch'} % Name of the condition (=folder)
Channel: [1x1 struct] % Channel file for the folder
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 source 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
% If 1, the trial is marked as bad in the explorer
Example: Getting the data structure.
>> sData = sStudy.Data(sAvgData(1).iItem) % Get the structure representing the file from sStudy
sData =
FileName: 'Subject01/S01_AEF_20131218_01_600Hz_notch/data_deviant_average_160513_1329.mat'
Comment: 'Avg: deviant (39 files)' % File comment, displayed in the database explorer
DataType: 'recordings' % Type of data in the file (mostly "recordings")
BadTrial: 0
Example: Getting the subject structure.
>> sSubject = bst_get('Subject', sStudy.BrainStormSubject) % Get subject structure from filename
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 in the subject folder
Surface: [1x9 struct] % List of surfaces in the subject folder
iAnatomy: 1 % Default MRI volume (in green, index of array Anatomy)
iScalp: 9 % Default head surface (index of array Surface)
iCortex: 4 % Default cortex surface (index of array Surface)
iInnerSkull: [] % Default inner skull surface (index of array Surface)
iOuterSkull: [] % Default outer skull surface (index of array Surface)
iOther: [] % Not used anymore
UseDefaultAnat: 0 % If 1: Subject uses the default anatomy
UseDefaultChannel: 0 % 0=one channel/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 of the Brainstorm distribution (may vary in compiled versions)
14 % - bst_get('UserReportsDir') : User reports directory (<home>/.brainstorm/reports/)
15 % - bst_get('UserMexDir') : User temporary directory (<home>/.brainstorm/mex/)
16 % - bst_get('UserProcessDir') : User custom processes directory (<home>/.brainstorm/process/)
17 % - bst_get('UserDefaultsDir') : User defaults directory (<home>/.brainstorm/defaults/)
18 % - bst_get('UserPluginsDir') : User plugins directory (brainstorm3/plugins/ if it exists, otherwise <home>/.brainstorm/plugins/)
19 % - bst_get('BrainstormDbFile') : User brainstorm.mat file (<home>/.brainstorm/brainstorm.mat)
20 % - bst_get('BrainstormDbDir') : User database directory (contains all the brainstorm protocols)
21 % - bst_get('DirDefaultSubject') : Directory name of the default subject
22 % - bst_get('DirDefaultStudy') : Directory name of the default study for each subject
23 % - bst_get('DirAnalysisInter') : Directory name of the inter-subject analysis study
24 % - bst_get('DirAnalysisIntra') : Directory name of the intra-subject analysis study (for each subject)
25 % - bst_get('AnatomyDefaults') : Get the contents of directory bstDir/defaults/anatomy
26 % - bst_get('MniAtlasDefaults') : Get the contents of directory bstDir/defaults/mniatlas
27 % - bst_get('EegDefaults') : Get the contents of directory bstDir/defaults/eeg
28 % - bst_get('LastUsedDirs') : Structure with all the last used directories (last used)
29 % - 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)
30 % - bst_get('FileFilters', DataType) : Get the list of import filters for a specific data type
31 % - bst_get('PluginCustomPath') : Full custom path to all plugins
32 % - bst_get('BrainSuiteDir') : Full path to a local installation of BrainSuite
33 % - bst_get('SpmTpmAtlas') : Full path to the SPM atlas TPM.nii
34 % - bst_get('PythonExe') : Path to the python executable
35 %
36 % ====== PROTOCOLS ====================================================================
37 % - bst_get('iProtocol') : Indice of current protocol
38 % - bst_get('Protocol', ProtocolName): Return the indice of the protocol ProtocolName, or [] if it doesn't exist
39 % - bst_get('ProtocolInfo') : Definition structure for current protocol
40 % - bst_get('ProtocolSubjects') : Subjects list for current protocol
41 % - bst_get('ProtocolStudies') : Studies list for current protocol
42 % - bst_get('isProtocolLoaded') : 1 if the protocol has been loaded, 0 else
43 % - bst_get('isProtocolModified') : 1 if the protocol has been modified, 0 else
44 %
45 % ====== STUDIES ======================================================================
46 % - bst_get('Study', StudyFileName) : Get one study in current protocol with its file name
47 % - bst_get('Study', iStudies) : Get one or more studies
48 % - bst_get('Study') : Get current study in current protocol
49 % - bst_get('StudyCount') : Get number of studies in the current protocol
50 % - bst_get('StudyWithSubject', SubjectFile) : Find studies associated with a given subject file (WITHOUT the system studies ('intra_subject', 'default_study'))
51 % - bst_get('StudyWithSubject', ..., 'intra_subject') : Find studies ... INCLUDING 'intra_subject' study
52 % - bst_get('StudyWithSubject', ..., 'default_study') : Find studies ... INCLUDING 'default_study' study
53 % - bst_get('StudyWithCondition', ConditionPath) : Find studies for a given condition path
54 % - bst_get('ChannelStudiesWithSubject', iSubjects) : Get all the studies where there should be a channel file for a list of subjects
55 % - bst_get('AnalysisIntraStudy', iSubject) : Get the default analysis study for target subject
56 % - bst_get('AnalysisInterStudy') : Get the default analysis study for inter-subject analysis
57 % - bst_get('DefaultStudy', iSubject) : Get the default study for target subject (by subject indice)
58 % - bst_get('DefaultStudy') : Get the global default study (common to all subjects)
59 % - bst_get('DefaultStudy', SubjectFile) : Get the default study for target subject (by filename)
60 % - bst_get('ChannelFile', ChannelFile) : Find a channel file in current protocol
61 % - bst_get('ChannelFileForStudy', StudyFile/DataFile) : Find a channel file in current protocol
62 % - bst_get('ChannelForStudy', iStudies) : Return current Channel struct for target study
63 % - bst_get('ChannelModalities', ChannelFile) : Return displayable modalities for a Channel file
64 % - bst_get('ChannelModalities', DataFile) : Return displayable modalities for a Data/Results/Timefreq... file
65 % - bst_get('ChannelDevice', ChannelFile) : Return acquisistion device for a channel file
66 % - bst_get('TimefreqDisplayModalities', TfFile) : Get displayable modalities for a TF file based on recordings
67 % - bst_get('HeadModelForStudy', iStudy) : Return current HeadModel struct for target study
68 % - bst_get('HeadModelFile', HeadModelFile) : Find a HeadModel file in current protocol
69 % - bst_get('HeadModelFile', HeadModelFile, iStudies): Find a HeadModel file in current protocol
70 % - bst_get('NoiseCovFile', NoiseCovFile) : Find a noise covariance file file in current protocol
71 % - bst_get('NoiseCovFile', NoiseCovFile, iStudies) : Find a noise covariance file in current protocol
72 % - bst_get('NoiseCovFile', DataCovFile) : Find a data covariance file file in current protocol
73 % - bst_get('NoiseCovFile', DataCovFile, iStudies) : Find a data covariance file file in current protocol
74 % - bst_get('DataFile', DataFile) : Find a DataFile in current protocol
75 % - bst_get('DataFile', DataFile, iStudies) : Find a DataFile in current protocol
76 % - bst_get('DataForDataList', iStudy, DataListName) : Find all the DataFiles grouped by a data list
77 % - bst_get('DataForStudy', iStudy) : Find all the Data files that are dependent on the channel/headmodel of a given study
78 % - bst_get('DataForStudies', iStudies)
79 % - bst_get('DataForChannelFile', ChannelFile) : Find all the DataFiles that use the given ChannelFile
80 % - bst_get('ResultsFile', ResultsFile) : Find a ResultsFile in current protocol
81 % - bst_get('ResultsFile', ResultsFile, iStudies) : Find a ResultsFile in input studies
82 % - bst_get('ResultsForDataFile', DataFile, iStudies): Find all results computed based on DataFile
83 % - bst_get('StatFile', StatFile) : Find a StatFile in current protocol
84 % - bst_get('StatFile', StatFile, iStudies) : Find a StatFile in input studies
85 % - bst_get('StatForDataFile', DataFile, iStudies)
86 % - bst_get('StatForDataFile', DataFile)
87 % - bst_get('TimefreqFile', TimefreqFile)
88 % - bst_get('TimefreqFile', TimefreqFile, iStudies)
89 % - bst_get('TimefreqForFile', FileName, iStudies) : Find all timefreq files computed based on target file
90 % - bst_get('TimefreqForKernel', KernelFile)
91 % - bst_get('DipolesFile', DipolesFile)
92 % - bst_get('DipolesFile', DipolesFile, iStudies)
93 % - bst_get('DipolesForFile', FileName, iStudies) : Find all dipoles files computed based on target file
94 % - bst_get('DipolesForKernel', KernelFile)
95 % - bst_get('MatrixFile', MatrixFile)
96 % - bst_get('MatrixFile', MatrixFile, iStudies)
97 % - bst_get('MatrixForMatrixList', iStudy, MatrixListName)
98 % - bst_get('AnyFile', AnyFile)
99 % - bst_get('AnyFile', AnyFile, iStudies)
100 % - bst_get('RelatedDataFile', FileName)
101 % - bst_get('RelatedDataFile', FileName, iStudies)
102 % - bst_get('GetFilenames')
103 %
104 % ====== SUBJECTS ======================================================================
105 % - bst_get('Subject', SubjectFileName, isRaw) : Find a subject in current protocol with its file name
106 % - bst_get('Subject', SubjectName, isRaw) : Find a subject in current protocol with its name
107 % - bst_get('Subject', iSubject) : Get a subject (normal or default if iSubject==0)
108 % - bst_get('Subject') : Get current subject in current protocol
109 % - bst_get('SubjectCount') : Get number of studies in the current protocol
110 % - bst_get('NormalizedSubjectName') : Name of the subject with a normalized anatomy
111 % - bst_get('NormalizedSubject') : Get groupd analysis subject for the current protocol
112 % - bst_get('ConditionsForSubject', SubjectFile) : Find all conditions for a given subject
113 % - bst_get('SurfaceFile', SurfaceFile) : Find a surface in current protocol
114 % - bst_get('SurfaceFileByType', iSubject, SurfaceType) : Find surfaces with given type for subject #i (default only)
115 % - bst_get('SurfaceFileByType', SubjectFile, SurfaceType) : Find surfaces with given type for subject SubjectFile (default only)
116 % - bst_get('SurfaceFileByType', SurfaceName, SurfaceType) : Find surfaces with given type for subject that also has surface SurfaceName (default only)
117 % - bst_get('SurfaceFileByType', MriName, SurfaceType) : Find surfaces with given type for subject that also has MRI MriName (default only)
118 % - bst_get('SurfaceFileByType', ..., ..., isDefaultOnly) : If 0, return all the surfaces of the given type, instead of only the default surface
119 % - bst_get('MriFile', MriFile) : Find a MRI in current protocol
120 %
121 % ====== GUI =================================================================
122 % - bst_get('BstControls') : Return main Brainstorm GUI structure
123 % - bst_get('BstFrame') : Return main Brainstorm JFrame
124 % - bst_get('isGUI') : Return 1 if the Brainstorm interface is displayed
125 % - bst_get('GuiLevel') : Return GUI level: -1=server, 0=nogui, 1=normal, 2=autopilot
126 % - bst_get('ScreenDef') : Get screens configuration
127 % - bst_get('DecorationSize') : Get dimensions of the windows decorations
128 % - bst_get('Layout') : Configuration of the main Brainstorm window
129 % - bst_get('Layout', prop) : Get one property in the layout properties
130 % - bst_get('PanelContainer') : Display list of registered panel containers
131 % - bst_get('PanelContainer', ContainerName) : Get a panel container handle
132 % - bst_get('Panel') : Display list of registered panels
133 % - bst_get('Panel', PanelName) : Find a panel with its name
134 % - bst_get('PanelControls', PanelName) : Get the controls of a panel
135 % - bst_get('Clipboard') : Nodes that were copied from the interface
136 % - bst_get('FigFont') : Standard font size displayed in the figures
137 % - bst_get('Font') : Create a Java font, scaled for the operating system
138 %
139 % ====== CONFIGURATION =================================================================
140 % - bst_get('Version') : Brainstorm version
141 % - bst_get('MatlabVersion') : Matlab version (version number * 100, eg. 801)
142 % - bst_get('MatlabReleaseName') : Matlab version (release name, eg. "R2014a")
143 % - bst_get('JavaVersion') : Java version
144 % - bst_get('isJavacomponent') : Returns 1 if javacomponent is available (Matlab < 2019b), 0 otherwise
145 % - bst_get('SystemMemory') : Amount of memory available, in Mb
146 % - bst_get('ByteOrder') : {'l','b'} - Byte order used to read and save binary files
147 % - bst_get('TSDisplayMode') : {'butterfly','column'}
148 % - bst_get('ElectrodeConfig', Modality) : Structure describing the current display values for SEEG/ECOG/EEG contacts
149 % - bst_get('AutoUpdates') : {0,1} - If 1, check automatically for updates at startup
150 % - bst_get('ForceMatCompression') : {0,1} - If 1, always save mat-files using the v7 format instead of v6
151 % - bst_get('IgnoreMemoryWarnings') : {0,1} - If 1, do not display memory warnings at the Brainstorm startup
152 % - bst_get('ExpertMode') : {0,1} - If 1, show advanced options that regular user do not see
153 % - bst_get('DisplayGFP') : {0,1} - If 1, the GFP is displayed on all the time series figures
154 % - bst_get('DownsampleTimeSeries') : {0,1,...} - If > 0, downsample dense time series for faster display
155 % - bst_get('DisableOpenGL') : {0,1,2} - If 1, do not use OpenGL renderer; if 2, use software OpenGL
156 % - bst_get('InterfaceScaling') : {100,125,150,...} - Scales the Brainstorm GUI by a fixed factor
157 % - bst_get('GraphicsSmoothing') : {0,1} - If 1, uses the graphics smoothing (Matlab >= 2014b)
158 % - bst_get('SystemCopy') : {0,1} - If 1, uses the system calls mv/cp instead of movefile/copyfile (Linux only)
159 % - bst_get('DefaultFormats') : Default formats for importing/exporting data, channels, ... (last used)
160 % - bst_get('BFSProperties') : Conductivities and thicknesses for 3-shell spherical forward model
161 % - bst_get('ImportDataOptions') : Import options for recordings
162 % - bst_get('ImportEegRawOptions') : Importation options for RAW EEG format
163 % - bst_get('BugReportOptions') : Bug reporter options
164 % - bst_get('DefaultSurfaceDisplay') : Default display options for surfaces (smooth, data threshold, sulci map)
165 % - bst_get('MagneticExtrapOptions') : Structure with the options for magnetic field extrapolation
166 % - bst_get('DefaultFreqBands')
167 % - bst_get('TimefreqOptions_morlet')
168 % - bst_get('TimefreqOptions_fft')
169 % - bst_get('TimefreqOptions_psd')
170 % - bst_get('TimefreqOptions_hilbert')
171 % - bst_get('OpenMEEGOptions')
172 % - bst_get('DuneuroOptions')
173 % - bst_get('GridOptions_headmodel')
174 % - bst_get('GridOptions_dipfit')
175 % - bst_get('UniformizeTimeSeriesScales') : {0,1} - If 1, the Y-axis of all the time series figures have the scale
176 % - bst_get('FlipYAxis') : {0,1} - If 1, the recordings are displayed with the negative values UP
177 % - bst_get('AutoScaleY') : {0,1} - If 1, the axis limits are updated when the figure is updated
178 % - bst_get('ShowXGrid') : {0,1} - If 1, show the XGrid in the time series figures
179 % - bst_get('ShowYGrid') : {0,1} - If 1, show the YGrid in the time series figures
180 % - bst_get('ShowZeroLines') : {0,1} - If 1, show the Y=0 lines in the columns view
181 % - bst_get('ShowEventsMode') : {'dot','line','none'}
182 % - bst_get('Resolution') : [resX,resY] fixed resolutions for X and Y axes
183 % - bst_get('FixedScaleY', Modality) : Struct with the scales to impose on the recordings for the selected modality
184 % - bst_get('XScale', XScale) : {'log', 'linear'}
185 % - bst_get('YScale', YScale) : {'log', 'linear'}
186 % - bst_get('UseSigProcToolbox') : Use Matlab's Signal Processing Toolbox when available
187 % - bst_get('RawViewerOptions', sFile) : Display options for RAW recordings, adapt for specific file
188 % - bst_get('RawViewerOptions') : Display options for RAW recordings
189 % - bst_get('TopoLayoutOptions') : Display options for 2DLayout display
190 % - bst_get('StatThreshOptions') : Options for online statistical thresholding
191 % - bst_get('ContactSheetOptions') : Display options for contact sheets
192 % - bst_get('ProcessOptions') : Options related with the data processing
193 % - bst_get('CustomColormaps') : Gets the list of user defined colormaps
194 % - bst_get('MriOptions') : Configuration for MRI display
195 % - bst_get('DigitizeOptions') : Digitizer options
196 % - bst_get('ReadOnly') : Read only interface
197 % - bst_get('NodelistOptions') : Structure with the options for file selection in the Process1 and Process2 panels
198 % - bst_get('ResizeFunction') : Get the appropriate resize function
199 % - bst_get('groot') : Get the root graphic object
200 % - bst_get('JFrame', hFig) : Get the underlying java frame for a Matlab figure
201 % - bst_get('LastPsdDisplayFunction') : Display option of measure for spectrum (log, power, magnitude, etc.)
202 % - bst_get('PlotlyCredentials') : Get the credentials and URL to connect to plot.ly server
203 % - bst_get('ExportBidsOptions') : Additional metadata for BIDS export
204 %
205 % SEE ALSO bst_set
206
207 % @=============================================================================
208 % This function is part of the Brainstorm software:
209 % https://neuroimage.usc.edu/brainstorm
210 %
211 % Copyright (c) University of Southern California & McGill University
212 % This software is distributed under the terms of the GNU General Public License
213 % as published by the Free Software Foundation. Further details on the GPLv3
214 % license can be found at http://www.gnu.org/copyleft/gpl.html.
215 %
216 % FOR RESEARCH PURPOSES ONLY. THE SOFTWARE IS PROVIDED "AS IS," AND THE
217 % UNIVERSITY OF SOUTHERN CALIFORNIA AND ITS COLLABORATORS DO NOT MAKE ANY
218 % WARRANTY, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
219 % MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, NOR DO THEY ASSUME ANY
220 % LIABILITY OR RESPONSIBILITY FOR THE USE OF THIS SOFTWARE.
221 %
222 % For more information type "brainstorm license" at command prompt.
223 % =============================================================================@
224 %
225 % Authors: Francois Tadel, 2008-2022
226 % Martin Cousineau, 2017
227
228 %% ==== PARSE INPUTS ====
229 global GlobalData;
230 if ((nargin >= 1) && ischar(varargin{1}))
231 contextName = varargin{1};
232 else
233 return
234 end
235 % Initialize returned variable
236 argout1 = [];
237 argout2 = [];
238 argout3 = [];
239 argout4 = [];
240 argout5 = [];
241
242 % Get required context structure
243 switch contextName
244 %% ==== SUBFUNCTIONS =====
245 case 'findFileInStudies'
246 [argout1, argout2, argout3] = findFileInStudies(varargin{2:end});
247
248 %% ==== BRAINSTORM CONFIGURATION ====
249 case 'Version'
250 argout1 = GlobalData.Program.Version;
251
252 case 'MatlabVersion'
253 if ~exist('version','builtin')
254 Version = 601;
255 else
256 % Get version number
257 str_vers = version();
258 vers = sscanf(str_vers, '%d.%d%*s');
259 if isempty(vers) || any(~isnumeric(vers)) || any(isnan(vers))
260 vers = 0;
261 end
262 Version = 100 * vers(1) + vers(2);
263 % Get release name
264 ipar = [find(str_vers == '('), find(str_vers == ')')];
265 end
266 argout1 = Version;
267
268 case 'MatlabReleaseName'
269 if ~exist('version','builtin')
270 Release = 'Matlab6';
271 else
272 % Get version number
273 str_vers = version();
274 % Get release name
275 ipar = [find(str_vers == '('), find(str_vers == ')')];
276 Release = str_vers(ipar(1)+1:ipar(2)-1);
277 end
278 argout1 = Release;
279
280 case 'JavaVersion'
281 strver = char(java.lang.System.getProperty('java.version'));
282 iDot = find(strver == '.');
283 if (length(iDot) < 2)
284 argout1 = str2num(strver);
285 else
286 argout1 = str2num(strver(1:iDot(2)-1));
287 end
288
289 case 'isJavacomponent'
290 % After Matlab 2019b, javacomponent() and JavaFrame property have been deprecated
291 argout1 = (bst_get('MatlabVersion') <= 906);
292
293 case 'SystemMemory'
294 maxvar = [];
295 totalmem = [];
296 if ispc && (bst_get('MatlabVersion') >= 706)
297 try
298 % Get memory info
299 usermem = memory();
300 maxvar = round(usermem.MaxPossibleArrayBytes / 1024 / 1024);
301 totalmem = round(usermem.MemAvailableAllArrays / 1024 / 1024);
302 catch
303 % Whatever...
304 end
305 end
306 argout1 = maxvar;
307 argout2 = totalmem;
308
309 case 'BrainstormHomeDir'
310 argout1 = GlobalData.Program.BrainstormHomeDir;
311 case 'BrainstormDbDir'
312 argout1 = GlobalData.DataBase.BrainstormDbDir;
313 case 'UserDir'
314 try
315 if ispc
316 userDir = getenv('USERPROFILE');
317 else
318 userDir = char(java.lang.System.getProperty('user.home'));
319 end
320 catch
321 userDir = '';
322 end
323 if isempty(userDir)
324 userDir = bst_get('BrainstormHomeDir');
325 end
326 argout1 = userDir;
327
328 case 'BrainstormUserDir'
329 bstUserDir = bst_fullfile(bst_get('UserDir'), '.brainstorm');
330 if ~isdir(bstUserDir)
331 res = mkdir(bstUserDir);
332 if ~res
333 error(['Cannot create Brainstorm user directory: "' bstUserDir '".']);
334 end
335 end
336 argout1 = bstUserDir;
337
338 case 'BrainstormTmpDir'
339 tmpDir = '';
340 isForcedDefault = ((nargin >= 2) && varargin{2});
341 % Default folder: userdir/tmp
342 defDir = bst_fullfile(bst_get('BrainstormUserDir'), 'tmp');
343 % If temporary directory is set in the preferences
344 if ~isForcedDefault && isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BrainstormTmpDir')
345 tmpDir = GlobalData.Preferences.BrainstormTmpDir;
346 end
347 % Else: use directory userdir/tmp
348 if isempty(tmpDir)
349 tmpDir = defDir;
350 end
351 % Create directory if it does not exist yet
352 if ~isdir(tmpDir)
353 res = mkdir(tmpDir);
354 if ~res && ~strcmp(tmpDir, defDir)
355 disp(['BST> Cannot create Brainstorm temporary directory: "' tmpDir '".']);
356 disp(['BST> Using default directory instead: "' defDir '".']);
357 % Create temporary folder
358 tmpDir = defDir;
359 if ~isdir(tmpDir)
360 res = mkdir(tmpDir);
361 else
362 res = 1;
363 end
364 end
365 % Error: cannot create any temporary folder
366 if ~res
367 error(['Cannot create Brainstorm temporary directory: "' tmpDir '".']);
368 end
369 end
370 argout1 = tmpDir;
371
372 case 'BrainstormDocDir'
373 docDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'doc');
374 if ~exist(docDir, 'file')
375 % Matlab compiler >= 2018b stores 'doc' under 'bst_javabuil'
376 docDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'bst_javabuil', 'doc');
377 if ~exist(docDir, 'file')
378 docDir = '';
379 disp('BST> Could not find "doc" folder.');
380 disp(['BST> BrainstormHomeDir = ' GlobalData.Program.BrainstormHomeDir]);
381 end
382 end
383 argout1 = docDir;
384
385 case 'BrainstormDefaultsDir'
386 defaultsDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'defaults');
387 if ~exist(defaultsDir, 'file')
388 % Matlab compiler >= 2018b stores 'defaults' under 'bst_javabuil'
389 defaultsDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'bst_javabuil', 'defaults');
390 if ~exist(defaultsDir, 'file')
391 defaultsDir = '';
392 disp('BST> Could not find "defaults" folder.');
393 disp(['BST> BrainstormHomeDir = ' GlobalData.Program.BrainstormHomeDir]);
394 end
395 end
396 argout1 = defaultsDir;
397
398 case 'UserReportsDir'
399 reportDir = bst_fullfile(bst_get('BrainstormUserDir'), 'reports');
400 if ~isdir(reportDir)
401 res = mkdir(reportDir);
402 if ~res
403 error(['Cannot create user reports directory: "' reportDir '".']);
404 end
405 end
406 argout1 = reportDir;
407
408 case 'UserMexDir'
409 mexDir = bst_fullfile(bst_get('BrainstormUserDir'), 'mex');
410 if ~isdir(mexDir)
411 res = mkdir(mexDir);
412 if ~res
413 error(['Cannot create Brainstorm mex-files directory: "' mexDir '".']);
414 end
415 end
416 argout1 = mexDir;
417
418 case 'UserProcessDir'
419 processDir = bst_fullfile(bst_get('BrainstormUserDir'), 'process');
420 if ~isdir(processDir)
421 res = mkdir(processDir);
422 if ~res
423 error(['Cannot create Brainstorm custom processes directory: "' processDir '".']);
424 end
425 end
426 argout1 = processDir;
427
428 case 'UserDefaultsDir'
429 defDir = bst_fullfile(bst_get('BrainstormUserDir'), 'defaults');
430 defDirAnat = bst_fullfile(defDir, 'anatomy');
431 defDirEeg = bst_fullfile(defDir, 'eeg');
432 if ~isdir(defDir)
433 res = mkdir(defDir);
434 if ~res
435 error(['Cannot create user templates directory: "' defDir '".']);
436 end
437 end
438 if ~isdir(defDirAnat)
439 res = mkdir(defDirAnat);
440 if ~res
441 error(['Cannot create user templates directory: "' defDirAnat '".']);
442 end
443 end
444 if ~isdir(defDirEeg)
445 res = mkdir(defDirEeg);
446 if ~res
447 error(['Cannot create user templates directory: "' defDirEeg '".']);
448 end
449 end
450 argout1 = defDir;
451
452 case 'UserPluginsDir'
453 % If brainstorm/plugins exists, use it (case of an environment exported and reused)
454 pluginsDir = bst_fullfile(GlobalData.Program.BrainstormHomeDir, 'plugins');
455 % Otherwise (standard case): <home>/.brainstorm/plugins/
456 if ~exist(pluginsDir, 'file')
457 pluginsDir = bst_fullfile(bst_get('BrainstormUserDir'), 'plugins');
458 if ~isdir(pluginsDir)
459 res = mkdir(pluginsDir);
460 if ~res
461 error(['Cannot create plugins directory: "' pluginsDir '".']);
462 end
463 end
464 end
465 argout1 = pluginsDir;
466
467 case 'BrainstormDbFile'
468 argout1 = bst_fullfile(bst_get('BrainstormUserDir'), 'brainstorm.mat');
469
470 %% ==== PROTOCOL ====
471 case 'iProtocol'
472 if isempty(GlobalData.DataBase.iProtocol)
473 argout1 = 0;
474 else
475 argout1 = GlobalData.DataBase.iProtocol;
476 end
477
478 case 'Protocol'
479 if ~isempty(GlobalData.DataBase.ProtocolInfo)
480 argout1 = find(strcmpi({GlobalData.DataBase.ProtocolInfo.Comment}, varargin{2}));
481 else
482 argout1 = [];
483 end
484
485 case {'ProtocolInfo', 'ProtocolSubjects', 'ProtocolStudies', 'isProtocolLoaded', 'isProtocolModified'}
486 argout2 = GlobalData.DataBase.iProtocol;
487 % No protocol: return empty matrix
488 if isempty(argout2) || ~isnumeric(argout2) || argout2 == 0
489 return;
490 end
491 % Check index integrity
492 if ((argout2 <= 0) || (argout2 > length(GlobalData.DataBase.ProtocolInfo))), warning('Brainstorm:InvalidIndex', 'Invalid index'), return, end
493 % Get requested protocol structure
494 argout1 = GlobalData.DataBase.(contextName)(argout2);
495
496
497 %% ==== STUDY ====
498 % Usage: [sStudy, iStudy] = bst_get('Study', StudyFileName)
499 % [sStudy, iStudy] = bst_get('Study')
500 % [sStudy, iStudy] = bst_get('Study', iStudies)
501 case 'Study'
502 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
503 return;
504 end
505 % Get list of current protocols
506 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
507 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
508 % Get list of current protocol studies
509 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
510 return;
511 end
512 % ===== PARSE INPUTS =====
513 if (nargin < 2)
514 % Call: bst_get('Study');
515 iStudies = ProtocolInfo.iStudy;
516 StudyFileName = [];
517 elseif (isnumeric(varargin{2}))
518 iStudies = varargin{2};
519 StudyFileName = [];
520 elseif (ischar(varargin{2}))
521 iStudies = [];
522 StudyFileName = strrep(varargin{2}, ProtocolInfo.STUDIES, '');
523 end
524 % Indices
525 iAnalysisStudy = -2; % CANNOT USE -1 => DISABLES SEARCH FUNCTIONS
526 iDefaultStudy = -3;
527 % Indices > 0: normal studies indiced in ProtocolStudies.Study array
528
529 % ===== GET STUDY BY INDEX =====
530 % Call: bst_get('Study', iStudies);
531 if ~isempty(iStudies)
532 argout1 = repmat(ProtocolStudies.DefaultStudy, 0);
533 % Get analysis study
534 iTargetAnalysis = find(iStudies == iAnalysisStudy);
535 if ~isempty(iTargetAnalysis)
536 argout1(iTargetAnalysis) = repmat(ProtocolStudies.AnalysisStudy, size(iTargetAnalysis));
537 argout2(iTargetAnalysis) = repmat(iAnalysisStudy, size(iTargetAnalysis));
538 end
539 % Get default study
540 iTargetDefault = find(iStudies == iDefaultStudy);
541 if ~isempty(iTargetDefault)
542 argout1(iTargetDefault) = repmat(ProtocolStudies.DefaultStudy, size(iTargetDefault));
543 argout2(iTargetDefault) = repmat(iDefaultStudy, size(iTargetDefault));
544 end
545 % Get normal studies
546 iTargetNormal = find((iStudies >= 1) & (iStudies <= length(ProtocolStudies.Study)));
547 if ~isempty(iTargetNormal)
548 argout1(iTargetNormal) = ProtocolStudies.Study(iStudies(iTargetNormal));
549 argout2(iTargetNormal) = iStudies(iTargetNormal);
550 end
551 % Error
552 if isempty(argout1)
553 GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol).iStudy = [];
554 end
555
556 % ===== GET STUDY BY FILENAME =====
557 % Call: bst_get('Study', StudyFileName);
558 elseif ~isempty(StudyFileName)
559 % NORMAL STUDY
560 iStudy = find(file_compare({ProtocolStudies.Study.FileName}, StudyFileName), 1);
561 % If a study is found : return it
562 if ~isempty(iStudy)
563 argout1 = ProtocolStudies.Study(iStudy);
564 argout2 = iStudy;
565 % DEFAULT STUDY
566 elseif ~isempty(ProtocolStudies.DefaultStudy) && file_compare({ProtocolStudies.DefaultStudy.FileName}, StudyFileName)
567 argout1 = ProtocolStudies.DefaultStudy;
568 argout2 = iDefaultStudy;
569 % ANALYSIS STUDY
570 elseif ~isempty(ProtocolStudies.AnalysisStudy) && file_compare({ProtocolStudies.AnalysisStudy.FileName}, StudyFileName)
571 argout1 = ProtocolStudies.AnalysisStudy;
572 argout2 = iAnalysisStudy;
573 end
574 else
575 return
576 end
577
578
579 %% ==== STUDY WITH SUBJECT FILE ====
580 % Usage : [sStudies, iStudies] = bst_get('StudyWithSubject', SubjectFile) : WITHOUT the system studies ('intra_subject', 'default_study')
581 % [sStudies, iStudies] = bst_get(..., 'intra_subject', 'default_study') : WITH the system studies: 'intra_subject' | 'default_study'
582 case 'StudyWithSubject'
583 % Parse inputs
584 if (nargin < 2) || ~ischar(varargin{2})
585 error('Invalid call to bst_get()');
586 end
587 if (nargin > 2)
588 IntraStudies = any(strcmpi(varargin(3:end), 'intra_subject'));
589 DefaultStudies = any(strcmpi(varargin(3:end), 'default_study'));
590 else
591 IntraStudies = 0;
592 DefaultStudies = 0;
593 end
594 SubjectFile = {varargin{2}};
595 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
596 return;
597 end
598 % Get list of current protocol description
599 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
600 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
601 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
602 return;
603 end
604
605 % Get default subject
606 sDefaultSubject = bst_get('Subject', 0);
607 % If SubjectFile is the default subject filename
608 if ~isempty(sDefaultSubject) && ~isempty(sDefaultSubject.FileName) && file_compare( SubjectFile{1}, sDefaultSubject.FileName)
609 % Get all the subjects files that use default anatomy
610 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
611 iSubjectUseDefaultAnat = find([ProtocolSubjects.Subject.UseDefaultAnat]);
612 if isempty(iSubjectUseDefaultAnat)
613 return
614 end
615 SubjectFile = {ProtocolSubjects.Subject(iSubjectUseDefaultAnat).FileName};
616 % Also updates inter-subject node
617 isInterSubject = 1;
618 else
619 isInterSubject = 0;
620 end
621 % Search all the current protocol's studies
622 iStudies = [];
623 for i=1:length(SubjectFile)
624 iStudies = [iStudies, find(file_compare({ProtocolStudies.Study.BrainStormSubject}, SubjectFile{i}))];
625 end
626 % Return results
627 if ~isempty(iStudies)
628 % Remove "analysis_intra" and "default_study" studies from list
629 if ~IntraStudies
630 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Name}, bst_get('DirAnalysisIntra'))) = [];
631 end
632 if ~DefaultStudies
633 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Name}, bst_get('DirDefaultStudy'))) = [];
634 end
635 % Return studies
636 argout1 = ProtocolStudies.Study(iStudies);
637 argout2 = iStudies;
638 else
639 argout1 = repmat(db_template('Study'), 0);
640 argout2 = [];
641 end
642 % Add inter-subject node, if needed
643 if isInterSubject
644 [sInterStudy, iInterStudy] = bst_get('AnalysisInterStudy');
645 argout1 = [argout1, sInterStudy];
646 argout2 = [argout2, iInterStudy];
647 end
648
649
650 %% ==== STUDY WITH CONDITION PATH ====
651 % USAGE: [sStudies, iStudies] = bst_get('StudyWithCondition', ConditionPath)
652 %
653 % INPUT: ConditionPath
654 % - 'SubjectName/conditionName' : Target condition for the specified subject
655 % - 'SubjectName/@intra' : Intra-subject condition for the subject
656 % - 'SubjectName/@default_study' : Default condition for the subject (where the subject's shared files are stored)
657 % - '*/conditionName' : Target condition for all the subjects
658 % - '@inter' : Inter-subject condition
659 % - '@default_study' : Protocol's default condition (where the protocol's shared files are stored)
660
661 case 'StudyWithCondition'
662 % Parse inputs
663 if (nargin ~= 2) || ~ischar(varargin{2})
664 error('Invalid call to bst_get()');
665 end
666 ConditionPath = varargin{2};
667 % Get list of current protocol description
668 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
669 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
670 if isempty(ProtocolStudies) || isempty(ProtocolInfo)
671 return;
672 end
673
674 % ConditionPath = @inter
675 if strcmpi(ConditionPath, '@inter')
676 iStudy = -2;
677 argout2 = iStudy;
678 argout1 = bst_get('Study', iStudy);
679 % ConditionPath = @default_study
680 elseif strcmpi(ConditionPath, '@default_study')
681 iStudy = -3;
682 argout2 = iStudy;
683 argout1 = bst_get('Study', iStudy);
684 % ConditionPath = SubjectName/ConditionName
685 else
686 % Get subject and condition names
687 condSplit = str_split(ConditionPath);
688 if (length(condSplit) ~= 2)
689 error('Invalid condition path.');
690 end
691 SubjectName = condSplit{1};
692 ConditionName = condSplit{2};
693
694 % If first element is '*', search for condition in all the studies
695 if (SubjectName(1) == '*')
696 iStudies = 1:length(ProtocolStudies.Study);
697 % Else : search for condition only in studies that are linked to the subject specified in the ConditionPath
698 else
699 % Get subject
700 sSubject = bst_get('Subject', SubjectName, 1);
701 if isempty(sSubject)
702 return;
703 end
704 iStudies = find(file_compare({ProtocolStudies.Study.BrainStormSubject}, sSubject.FileName));
705 end
706 % Nothing to search
707 if isempty(iStudies)
708 return
709 end
710
711 % Search all the current protocol's studies
712 iStudies = iStudies(cellfun(@(c)isequal(ConditionName, c), [ProtocolStudies.Study(iStudies).Condition]));
713 % Return results
714 if ~isempty(iStudies)
715 % Remove "analysis_intra" and "default_study" studies from list
716 if ~strcmpi(ConditionName, '@intra')
717 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Condition}, bst_get('DirAnalysisIntra'))) = [];
718 end
719 if ~strcmpi(ConditionName, '@default_study')
720 iStudies(strcmpi({ProtocolStudies.Study(iStudies).Condition}, bst_get('DirDefaultStudy'))) = [];
721 end
722 % Sort by subject
723 if (length(iStudies) > 1)
724 SubjNameList = cell(1,length(iStudies));
725 % For each study, get subject name
726 for i = 1:length(iStudies)
727 sSubject = bst_get('Subject', ProtocolStudies.Study(iStudies(i)).BrainStormSubject);
728 SubjNameList{i} = sSubject.Name;
729 end
730 % Sort subjects names
731 [sortSubjList, iSort] = sort(SubjNameList);
732 % Apply same sorting to studies
733 iStudies = iStudies(iSort);
734 end
735 % Return studies
736 argout1 = ProtocolStudies.Study(iStudies);
737 argout2 = iStudies;
738 else
739 argout1 = repmat(db_template('Study'), 0);
740 argout2 = [];
741 end
742 end
743
744 %% ==== CHANNEL STUDIES WITH SUBJECT ====
745 % Usage: iStudies = bst_get('ChannelStudiesWithSubject', iSubjects, 'NoIntra')
746 case 'ChannelStudiesWithSubject'
747 % Parse inputs
748 if (nargin >= 2) && isnumeric(varargin{2})
749 iSubjects = varargin{2};
750 else
751 error('Invalid call to bst_get()');
752 end
753 if (nargin == 3) && strcmpi(varargin{3}, 'NoIntra')
754 NoIntra = 1;
755 else
756 NoIntra = 0;
757 end
758 % Process all subjects
759 iStudies = [];
760 for i=1:length(iSubjects)
761 iSubject = iSubjects(i);
762 sSubject = bst_get('Subject', iSubject, 1);
763 % No subject: error
764 if isempty(sSubject)
765 continue
766 % If subject uses default channel file
767 elseif (sSubject.UseDefaultChannel ~= 0)
768 % Get default study for this subject
769 [tmp___, iStudiesNew] = bst_get('DefaultStudy', iSubject);
770 iStudies = [iStudies, iStudiesNew];
771 % Else: get all the studies belonging to this subject
772 else
773 if NoIntra
774 [tmp___, iStudiesNew] = bst_get('StudyWithSubject', sSubject.FileName);
775 else
776 [tmp___, iStudiesNew] = bst_get('StudyWithSubject', sSubject.FileName, 'intra_subject');
777 end
778 iStudies = [iStudies, iStudiesNew];
779 end
780 end
781 argout1 = iStudies;
782
783
784 %% ==== STUDIES COUNT ====
785 % Usage: [nbStudies] = bst_get('StudyCount')
786 case 'StudyCount'
787 % Nothing
788 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
789 argout1 = 0;
790 return;
791 end
792 % Get list of current protocol studies
793 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
794 argout1 = length(ProtocolStudies.Study);
795
796 %% ==== SUBJECTS COUNT ====
797 % Usage: [nbSubjects] = bst_get('SubjectCount')
798 case 'SubjectCount'
799 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
800 argout1 = 0;
801 return;
802 end
803 % Get list of current protocol studies
804 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
805 argout1 = length(ProtocolSubjects.Subject);
806
807 %% ==== NORMALIZED SUBJECT ====
808 case 'NormalizedSubject'
809 % Get normalized subject name
810 normSubjName = 'Group_analysis';
811 % Try to get normalized subject
812 [sNormSubj, iNormSubj] = bst_get('Subject', normSubjName, 0);
813 % If normalized subject does not exist: create it
814 if isempty(sNormSubj)
815 % Always use default anatomy
816 UseDefaultAnat = 1;
817 % If all the subjects use a global channel file: Use global default as well
818 if ~isempty(GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol).Subject) && ...
819 all([GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol).Subject.UseDefaultChannel] == 2)
820 UseDefaultChannel = 2;
821 else
822 UseDefaultChannel = 1;
823 end
824 % Create subject
825 [sNormSubj, iNormSubj] = db_add_subject(normSubjName, [], UseDefaultAnat, UseDefaultChannel);
826 % Get full subject structure
827 [sNormSubj, iNormSubj] = bst_get('Subject', normSubjName, 0);
828 end
829 argout1 = sNormSubj;
830 argout2 = iNormSubj;
831
832
833 %% ==== ANALYSIS STUDY (INTRA) ====
834 % Usage: [sAnalStudy, iAnalStudy] = bst_get('AnalysisIntraStudy', iSubject)
835 case 'AnalysisIntraStudy'
836 % Parse inputs
837 if (nargin == 2) && isnumeric(varargin{2})
838 iSubject = varargin{2};
839 else
840 error('Invalid call to bst_get()');
841 end
842 % Get subject
843 sSubject = bst_get('Subject', iSubject, 1);
844 % Get studies related to subject
845 [sSubjStudies, iSubjStudies] = bst_get('StudyWithSubject', sSubject.FileName, 'intra_subject');
846 % Look for the 'AnalysisIntra' study
847 iFound = find(cellfun(@(c)ismember(bst_get('DirAnalysisIntra'), c), {sSubjStudies.Condition}));
848 iAnalStudy = iSubjStudies(iFound);
849 sAnalStudy = sSubjStudies(iFound);
850 % Return found structure
851 argout1 = sAnalStudy;
852 argout2 = iAnalStudy;
853
854
855 %% ==== ANALYSIS STUDY (INTER) ====
856 % Usage: [sAnalStudyInter, iAnalStudyInter] = bst_get('AnalysisInterStudy')
857 case 'AnalysisInterStudy'
858 iAnalStudyInter = -2;
859 [argout1, argout2] = bst_get('Study', iAnalStudyInter);
860
861
862 %% ==== DEFAULT STUDY ====
863 % Usage: [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy', iSubject)
864 % [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy') : iSubject=0
865 % [sDefaulStudy, iDefaultStudy] = bst_get('DefaultStudy', SubjectFile)
866 case 'DefaultStudy'
867 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
868 return;
869 end
870 % Parse inputs
871 if (nargin == 1)
872 iSubject = 0;
873 elseif (nargin == 2) && isnumeric(varargin{2})
874 iSubject = varargin{2};
875 elseif (nargin == 2) && ischar(varargin{2})
876 SubjectFile = varargin{2};
877 % Get subject attached to study
878 [sSubject, iSubject] = bst_get('Subject', SubjectFile, 1);
879 if isempty(sSubject) || ~sSubject.UseDefaultChannel
880 return;
881 end
882 else
883 error('Invalid call to bst_get()');
884 end
885 % === DEFAULT SUBJECT ===
886 % => Return global default study
887 if (iSubject == 0)
888 % Get protocol's studies
889 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
890 % Return Global default study
891 argout1 = ProtocolStudies.DefaultStudy;
892 argout2 = -3;
893 % === NORMAL SUBJECT ===
894 else
895 % Get subject
896 sSubject = bst_get('Subject', iSubject, 1);
897 % === GLOBAL DEFAULT STUDY ===
898 if sSubject.UseDefaultChannel == 2
899 % Get protocol's studies
900 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
901 % Return Global default study
902 argout1 = ProtocolStudies.DefaultStudy;
903 argout2 = -3;
904 % === SUBJECT'S DEFAULT STUDY ===
905 elseif sSubject.UseDefaultChannel == 1
906 % Get studies related to subject
907 [sSubjStudies, iSubjStudies] = bst_get('StudyWithSubject', sSubject.FileName, 'default_study');
908 % Look for the 'DefaultStudy' study
909 iFound = find(cellfun(@(c)ismember(bst_get('DirDefaultStudy'), c), {sSubjStudies.Condition}));
910 iDefaultStudy = iSubjStudies(iFound);
911 sDefaultStudy = sSubjStudies(iFound);
912 % Return found structure
913 argout1 = sDefaultStudy;
914 argout2 = iDefaultStudy;
915 end
916 end
917
918
919
920 %% ==== SUBJECT ====
921 % Usage : [sSubject, iSubject] = bst_get('Subject', iSubject, isRaw)
922 % [sSubject, iSubject] = bst_get('Subject', SubjectFileName, isRaw);
923 % [sSubject, iSubject] = bst_get('Subject', SubjectName, isRaw);
924 % [sSubject, iSubject] = bst_get('Subject');
925 % If isRaw is set: force to return the real brainstormsubject description
926 % (ignoring wether it uses protocol's default anatomy or not)
927 case 'Subject'
928 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
929 return;
930 end
931 % Get list of current protocol subjects
932 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
933 sSubject = [];
934 SubjectName = [];
935 SubjectFileName = [];
936 % ISRAW parameter
937 if (nargin < 3)
938 isRaw = 0;
939 else
940 isRaw = varargin{3};
941 end
942 % Call: bst_get('subject', iSubject, isRaw);
943 if (nargin >= 2) && isnumeric(varargin{2})
944 iSubject = varargin{2};
945 if (iSubject > length(ProtocolSubjects.Subject))
946 error('Invalid subject indice.');
947 end
948 % If required subject is default subject (iSubject = 0)
949 if (iSubject == 0)
950 % Default subject available
951 if ~isempty(ProtocolSubjects.DefaultSubject)
952 sSubject = ProtocolSubjects.DefaultSubject;
953 % Default subject not available
954 else
955 return
956 end
957 % Normal subject
958 else
959 sSubject = ProtocolSubjects.Subject(iSubject);
960 end
961
962 % Call: bst_get('subject', SubjectFileName, isRaw);
963 % Call: bst_get('subject', SubjectName, isRaw);
964 elseif (nargin >= 2) && isempty(varargin{2})
965 % If study name is empty: use DefaultSubject
966 SubjectFileName = ProtocolSubjects.DefaultSubject.FileName;
967 elseif (nargin >= 2) && (ischar(varargin{2}))
968 [fName, fBase, fExt] = bst_fileparts(varargin{2});
969 % Argument is a Matlab .mat filename
970 if strcmpi(fExt, '.mat')
971 SubjectFileName = varargin{2};
972 % Else : assume argument is a directory
973 else
974 SubjectName = file_standardize(varargin{2});
975 end
976
977 % Call: bst_get('subject'); => looking for current subject
978 elseif (nargin < 2)
979 % Get current subject filename in current study
980 sStudy = bst_get('Study');
981 if isempty(sStudy)
982 return
983 end
984 SubjectFileName = sStudy.BrainStormSubject;
985 % If study's subject is not defined, get DefaultSubject
986 if isempty(SubjectFileName) && ~isempty(ProtocolSubjects.DefaultSubject)
987 SubjectFileName = ProtocolSubjects.DefaultSubject.FileName;
988 end
989 else
990 error('Invalid call to bst_get()');
991 end
992
993 % If Subject is defined by its filename/name
994 if isempty(sSubject)
995 % Look in Default Subject
996 if ~isempty(ProtocolSubjects.DefaultSubject) && (file_compare(ProtocolSubjects.DefaultSubject.FileName, SubjectFileName) ...
997 || strcmpi(ProtocolSubjects.DefaultSubject.Name, SubjectName))
998 sSubject = ProtocolSubjects.DefaultSubject;
999 iSubject = 0;
1000 % If not found : find target subject file name in normal subjects
1001 elseif ~isempty(SubjectFileName)
1002 iSubject = find(file_compare({ProtocolSubjects.Subject.FileName}, SubjectFileName), 1);
1003 sSubject = ProtocolSubjects.Subject(iSubject);
1004 elseif ~isempty(SubjectName)
1005 iSubject = find(file_compare({ProtocolSubjects.Subject.Name}, SubjectName), 1);
1006 sSubject = ProtocolSubjects.Subject(iSubject);
1007 else
1008 error('Subject name not specified.');
1009 end
1010 end
1011
1012 % Return found subject
1013 if ~isempty(iSubject) && ~isempty(sSubject)
1014 % If subject uses default subject
1015 if sSubject.UseDefaultAnat && ~isRaw && ~isempty(ProtocolSubjects.DefaultSubject) && ~isempty(ProtocolSubjects.DefaultSubject.FileName)
1016 % Return default subject (WITH REAL SUBJECT'S NAME)
1017 argout1 = ProtocolSubjects.DefaultSubject;
1018 argout1.Name = sSubject.Name;
1019 argout1.UseDefaultAnat = sSubject.UseDefaultAnat;
1020 argout1.UseDefaultChannel = sSubject.UseDefaultChannel;
1021 argout2 = iSubject;
1022 % Else, return found subject
1023 else
1024 argout1 = sSubject;
1025 argout2 = iSubject;
1026 end
1027 end
1028
1029
1030 %% ==== SURFACE FILE ====
1031 % Usage : [sSubject, iSubject, iSurface] = bst_get('SurfaceFile', SurfaceFile)
1032 case 'SurfaceFile'
1033 % No protocol in database
1034 if isempty(GlobalData) || isempty(GlobalData.DataBase) || isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1035 return;
1036 end
1037 % Get list of current protocol subjects
1038 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
1039 if isempty(ProtocolSubjects)
1040 return
1041 end;
1042
1043 % Parse inputs
1044 if (nargin == 2)
1045 SurfaceFile = varargin{2};
1046 else
1047 error('Invalid call to bst_get().');
1048 end
1049
1050 % Remove SUBJECTS path from SurfaceFile
1051 SurfaceFile = file_short(SurfaceFile);
1052 % Look for surface file in DefaultSubject
1053 if ~isempty(ProtocolSubjects.DefaultSubject)
1054 % Find the first surface that matches the SurfaceFile
1055 iSurface = find(file_compare(SurfaceFile, {ProtocolSubjects.DefaultSubject.Surface.FileName}), 1);
1056 % If a surface was found in default subject : return it
1057 if ~isempty(iSurface)
1058 argout1 = ProtocolSubjects.DefaultSubject;
1059 argout2 = 0;
1060 argout3 = iSurface;
1061 return
1062 end
1063 end
1064 % Look for surface file in all the surfaces of all subjects
1065 for iSubj = 1:length(ProtocolSubjects.Subject)
1066 % Find the first surface that matches the SurfaceFile
1067 iSurface = find(file_compare(SurfaceFile, {ProtocolSubjects.Subject(iSubj).Surface.FileName}), 1);
1068 % If a surface was found in current subject : return it
1069 if ~isempty(iSurface)
1070 argout1 = ProtocolSubjects.Subject(iSubj);
1071 argout2 = iSubj;
1072 argout3 = iSurface;
1073 return
1074 end
1075 end
1076
1077
1078 %% ==== SURFACE FILE BY TYPE ====
1079 % Usage : [sSurface, iSurface] = bst_get('SurfaceFileByType', iSubject, SurfaceType)
1080 % [sSurface, iSurface] = bst_get('SurfaceFileByType', SubjectFile, SurfaceType)
1081 % [sSurface, iSurface] = bst_get('SurfaceFileByType', SurfaceFile, SurfaceType)
1082 % [sSurface, iSurface] = bst_get('SurfaceFileByType', MriFile, SurfaceType)
1083 % [sSurface, iSurface] = bst_get('SurfaceFileByType', ..., SurfaceType, isDefaultOnly)
1084 case 'SurfaceFileByType'
1085 % By default: return only the default surfaces of the category
1086 if (nargin < 4)
1087 isDefaultOnly = 1;
1088 else
1089 isDefaultOnly = varargin{4};
1090 end
1091 % Get subject
1092 if isempty(varargin{2})
1093 % Get default subject
1094 sSubject = bst_get('Subject', 0);
1095 elseif ischar(varargin{2})
1096 FileName = varargin{2};
1097 sSubject = bst_get('AnyFile', FileName);
1098 else
1099 iSubject = varargin{2};
1100 sSubject = bst_get('Subject', iSubject);
1101 end
1102 % Error handling
1103 if isempty(sSubject)
1104 disp('BST> Warning: Subject not found.');
1105 return;
1106 elseif isempty(sSubject.Surface)
1107 return;
1108 end
1109 SurfaceType = varargin{3};
1110
1111 % === RETURN ONLY DEFAULTS ===
1112 if isDefaultOnly
1113 % Look for required surface type
1114 field = ['i' SurfaceType];
1115 if ~isfield(sSubject, field) || isempty(sSubject.(field))
1116 return
1117 end
1118 argout1 = sSubject.Surface(sSubject.(field));
1119 argout2 = sSubject.(field);
1120 % === RETURN ALL THE SURFACES ===
1121 else
1122 % Build the list of tagged surfaces
1123 fileTag = ['_' lower(SurfaceType)];
1124 iTargetList = find(cellfun(@(c)~isempty(strfind(c, fileTag)), {sSubject.Surface.FileName}));
1125 % Put the default cortex on top of the list
1126 iDefaults = intersect([sSubject.iCortex, sSubject.iScalp, sSubject.iInnerSkull, sSubject.iOuterSkull, sSubject.iFibers, sSubject.iFEM], iTargetList);
1127 if ~isempty(iDefaults)
1128 iTargetList = [iDefaults, setdiff(iTargetList, iDefaults)];
1129 end
1130 % Return all cortex surfaces
1131 argout1 = sSubject.Surface(iTargetList);
1132 argout2 = iTargetList;
1133 end
1134
1135
1136 %% ==== MRI FILE ====
1137 % Usage : [sSubject, iSubject, iMri] = bst_get('MriFile', MriFile)
1138 case 'MriFile'
1139 % No protocol in database
1140 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1141 return;
1142 end
1143 % Get list of current protocol subjects
1144 ProtocolSubjects = GlobalData.DataBase.ProtocolSubjects(GlobalData.DataBase.iProtocol);
1145 if isempty(ProtocolSubjects)
1146 return
1147 end
1148
1149 % Parse inputs
1150 if (nargin == 2)
1151 MriFile = varargin{2};
1152 else
1153 error('Invalid call to bst_get().');
1154 end
1155
1156 % Remove SUBJECTS path from MriFile
1157 MriFile = file_short(MriFile);
1158 % Look for MRI file in DefaultSubject
1159 if ~isempty(ProtocolSubjects.DefaultSubject)
1160 % Find the first MRI that matches the MriFile
1161 iMri = find(file_compare(MriFile, {ProtocolSubjects.DefaultSubject.Anatomy.FileName}), 1);
1162 % If a MRI was found in default subject : return it
1163 if ~isempty(iMri)
1164 argout1 = ProtocolSubjects.DefaultSubject;
1165 argout2 = 0;
1166 argout3 = iMri;
1167 return
1168 end
1169 end
1170 % Look for MRI file in all the MRIs of all subjects
1171 for iSubj = 1:length(ProtocolSubjects.Subject)
1172 % Find the first MRI that matches the MriFile
1173 iMri = find(file_compare(MriFile, {ProtocolSubjects.Subject(iSubj).Anatomy.FileName}), 1);
1174 % If a MRI was found in current subject : return it
1175 if ~isempty(iMri)
1176 argout1 = ProtocolSubjects.Subject(iSubj);
1177 argout2 = iSubj;
1178 argout3 = iMri;
1179 return
1180 end
1181 end
1182
1183
1184 %% ==== CHANNEL FILE ====
1185 % Usage: [sStudy, iStudy, iChannel] = bst_get('ChannelFile', ChannelFile)
1186 case 'ChannelFile'
1187 % No protocol in database
1188 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1189 return;
1190 end
1191 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1192 % Parse inputs
1193 if (nargin == 2)
1194 ChannelFile = varargin{2};
1195 ChannelFile = strrep(ChannelFile, ProtocolInfo.STUDIES, '');
1196 else
1197 error('Invalid call to bst_get().');
1198 end
1199 % Look for Channel file in all the surfaces of all subjects
1200 [argout1, argout2, argout3] = findFileInStudies('Channel', 'FileName', ChannelFile);
1201
1202
1203 %% ==== CHANNEL FILE FOR STUDY ====
1204 % Usage: [ChannelFile, sStudy, iStudy] = bst_get('ChannelFileForStudy', StudyFile/DataFile)
1205 case 'ChannelFileForStudy'
1206 % Parse inputs
1207 if (nargin == 2)
1208 StudyFile = varargin{2};
1209 else
1210 error('Invalid call to bst_get().');
1211 end
1212 % Get study in database
1213 [sStudy, iStudy] = bst_get('Study', StudyFile);
1214 % If data file instead on Study file
1215 if isempty(sStudy)
1216 [sStudy, iStudy] = bst_get('AnyFile', StudyFile);
1217 end
1218 sChannel = bst_get('ChannelForStudy', iStudy);
1219 if ~isempty(sChannel)
1220 argout1 = sChannel.FileName;
1221 argout2 = sStudy;
1222 argout3 = iStudy;
1223 else
1224 argout1 = [];
1225 end
1226
1227
1228 %% ==== CHANNEL STRUCT FOR STUDY ====
1229 % Usage: [sChannel, iChanStudy] = bst_get('ChannelForStudy', iStudies)
1230 case 'ChannelForStudy'
1231 % Parse inputs
1232 if (nargin == 2)
1233 iStudies = varargin{2};
1234 else
1235 error('Invalid call to bst_get().');
1236 end
1237 iChanStudies = [];
1238 sListChannel = [];
1239 for i = 1:length(iStudies)
1240 % Get study
1241 iStudy = iStudies(i);
1242 sStudy = bst_get('Study', iStudy);
1243 if isempty(sStudy)
1244 continue;
1245 end
1246 iChanStudy = iStudy;
1247 % === Analysis-Inter node ===
1248 iAnalysisInter = -2;
1249 iGlobalDefaultStudy = -3;
1250 if (iStudy == iAnalysisInter)
1251 % If no channel file is defined in 'Analysis-intra' node: look in
1252 if isempty(sStudy.Channel)
1253 % Get global default study
1254 sStudy = bst_get('Study', iGlobalDefaultStudy);
1255 iChanStudy = iGlobalDefaultStudy;
1256 end
1257 % === All other nodes ===
1258 else
1259 % Get subject attached to study
1260 [sSubject, iSubject] = bst_get('Subject', sStudy.BrainStormSubject, 1);
1261 if isempty(sSubject)
1262 return;
1263 end
1264 % Subject uses default channel/headmodel
1265 if (sSubject.UseDefaultChannel ~= 0)
1266 [sStudy, iChanStudy] = bst_get('DefaultStudy', iSubject);
1267 if isempty(sStudy)
1268 return
1269 end
1270 end
1271 end
1272 iChanStudies = [iChanStudies, iChanStudy];
1273 sListChannel = [sListChannel, sStudy.Channel];
1274 end
1275 % Return Channel structure
1276 argout1 = sListChannel;
1277 argout2 = iChanStudies;
1278
1279 %% ==== CHANNEL MODALITIES =====
1280 % Usage: [Modalities, DispMod, DefMod] = bst_get('ChannelModalities', ChannelFile)
1281 % [Modalities, DispMod, DefMod] = bst_get('ChannelModalities', DataFile/ResultsFile/TimefreqFile...)
1282 case 'ChannelModalities'
1283 % Get input file
1284 [sStudy, iStudy, iItem, DataType, sItem] = bst_get('AnyFile', varargin{2});
1285 % If channel file
1286 if strcmpi(DataType, 'channel')
1287 sChannel = sItem;
1288 else
1289 sChannel = bst_get('ChannelForStudy', iStudy);
1290 end
1291 % Return modalities
1292 if ~isempty(sChannel)
1293 % Get all modalities
1294 if ~isempty(sChannel.DisplayableSensorTypes)
1295 % Return the displayable sensors on top of the list
1296 argout1 = cat(2, sChannel.DisplayableSensorTypes, setdiff(sChannel.Modalities, sChannel.DisplayableSensorTypes));
1297 else
1298 argout1 = sChannel.Modalities;
1299 end
1300 % Get only sensors that have spatial representation
1301 argout2 = sChannel.DisplayableSensorTypes;
1302 % Default candidates
1303 if ~isempty(argout2)
1304 defList = argout2;
1305 else
1306 defList = argout1;
1307 end
1308 if isempty(defList)
1309 return;
1310 end
1311 % Remove EDF and BDF from the default list
1312 defList = setdiff(defList, {'EDF','BDF','KDF'});
1313 % Get default modality
1314 if ismember('SEEG', defList)
1315 argout3 = 'SEEG';
1316 elseif ismember('ECOG', defList)
1317 argout3 = 'ECOG';
1318 elseif any(ismember({'MEG','MEG GRAD','MEG MAG'}, defList))
1319 argout3 = 'MEG';
1320 elseif ismember('EEG', defList)
1321 argout3 = 'EEG';
1322 elseif ismember('NIRS', defList)
1323 argout3 = 'NIRS';
1324 else
1325 argout3 = defList{1};
1326 end
1327 % Place the default on top of the lists
1328 if ismember(argout3, argout1)
1329 argout1(strcmpi(argout1, argout3)) = [];
1330 argout1 = cat(2, argout3, argout1);
1331 end
1332 if ismember(argout3, argout2)
1333 argout2(strcmpi(argout2, argout3)) = [];
1334 argout2 = cat(2, argout3, argout2);
1335 end
1336 else
1337 argout1 = [];
1338 end
1339
1340
1341 %% ==== TIMEFREQ DISPLAY MODALITIES ====
1342 % Usage: DisplayMod = bst_get('TimefreqDisplayModalities', TimefreqFile)
1343 case 'TimefreqDisplayModalities'
1344 TimefreqFile = varargin{2};
1345 % Load sensor names from file
1346 TimefreqMat = in_bst_timefreq(TimefreqFile, 0, 'RowNames');
1347 % Get channel file
1348 ChannelFile = bst_get('ChannelFileForStudy', TimefreqFile);
1349 if isempty(ChannelFile)
1350 return;
1351 end
1352 % Load channel file
1353 ChannelMat = load(file_fullpath(ChannelFile), 'Channel');
1354 % Get channels that are present in the file
1355 [tmp__,I,J] = intersect({ChannelMat.Channel.Name}, TimefreqMat.RowNames);
1356 FileMod = unique({ChannelMat.Channel(I).Type});
1357 % Check if only one type of gradiometer is selected
1358 if isequal(FileMod, {'MEG GRAD'}) && all(cellfun(@(c)(c(end)=='2'), {ChannelMat.Channel(I).Name}))
1359 argout1 = {'MEG GRAD2'};
1360 elseif isequal(FileMod, {'MEG GRAD'}) && all(cellfun(@(c)(c(end)=='3'), {ChannelMat.Channel(I).Name}))
1361 argout1 = {'MEG GRAD3'};
1362 % Keep only the modalities that can be displayed (as topography)
1363 else
1364 argout1 = intersect(FileMod, {'MEG','MEG GRAD','MEG MAG','EEG','ECOG','SEEG','NIRS'});
1365 end
1366
1367
1368 %% ==== CHANNEL DEVICE ====
1369 % Usage: Device = bst_get('ChannelDevice', ChannelFile)
1370 case 'ChannelDevice'
1371 ChannelFile = varargin{2};
1372 if ~isempty(strfind(ChannelFile, 'vectorview306'))
1373 Device = 'Vectorview306';
1374 elseif ~isempty(strfind(ChannelFile, 'ctf_acc1'))
1375 Device = 'CTF';
1376 elseif ~isempty(strfind(ChannelFile, '4d_acc1'))
1377 Device = '4D';
1378 elseif ~isempty(strfind(ChannelFile, 'babysquid'))
1379 Device = 'BabySQUID';
1380 elseif ~isempty(strfind(ChannelFile, 'babymeg'))
1381 Device = 'BabyMEG';
1382 elseif ~isempty(strfind(ChannelFile, 'kit'))
1383 Device = 'KIT';
1384 elseif ~isempty(strfind(ChannelFile, 'ricoh'))
1385 Device = 'RICOH';
1386 elseif ~isempty(strfind(ChannelFile, 'kriss'))
1387 Device = 'KRISS';
1388 elseif ~isempty(strfind(ChannelFile, 'nirsbrs'))
1389 Device = 'NIRS-BRS';
1390 else
1391 Device = '';
1392 end
1393 argout1 = Device;
1394
1395
1396 %% ==== HEADMODEL STRUCT FOR STUDY ====
1397 % Usage: [sHeadModel] = bst_get('HeadModelForStudy', iStudy)
1398 case 'HeadModelForStudy'
1399 % Parse inputs
1400 if (nargin == 2)
1401 iStudy = varargin{2};
1402 else
1403 error('Invalid call to bst_get().');
1404 end
1405 % Get study
1406 sStudy = bst_get('Study', iStudy);
1407 % === Analysis-Inter node ===
1408 iAnalysisInter = -2;
1409 iGlobalDefaultStudy = -3;
1410 if (iStudy == iAnalysisInter)
1411 % If no channel file is defined in 'Analysis-intra' node: look in
1412 if isempty(sStudy.iHeadModel)
1413 % Get global default study
1414 sStudy = bst_get('Study', iGlobalDefaultStudy);
1415 end
1416 % === All other nodes ===
1417 else
1418 % Get subject attached to study
1419 [sSubject, iSubject] = bst_get('Subject', sStudy.BrainStormSubject, 1);
1420 if isempty(sSubject)
1421 return;
1422 end
1423 % Subject uses default channel/headmodel
1424 if (sSubject.UseDefaultChannel ~= 0)
1425 sStudy = bst_get('DefaultStudy', iSubject);
1426 if isempty(sStudy)
1427 return
1428 end
1429 end
1430 end
1431 % Return HeadModel structure
1432 if ~isempty(sStudy.iHeadModel)
1433 argout1 = sStudy.HeadModel(sStudy.iHeadModel(1));
1434 else
1435 argout1 = [];
1436 end
1437
1438
1439 %% ==== HEADMODEL FILE ====
1440 % Usage: [sStudy, iStudy, iHeadModel] = bst_get('HeadModelFile', HeadModelFile, iStudies)
1441 % [sStudy, iStudy, iHeadModel] = bst_get('HeadModelFile', HeadModelFile)
1442 case 'HeadModelFile'
1443 % No protocol in database
1444 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1445 return;
1446 end
1447 % Input #2: HeadModelFile
1448 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1449 HeadModelFile = varargin{2};
1450 HeadModelFile = strrep(HeadModelFile, ProtocolInfo.STUDIES, '');
1451 % Input #3: iStudies
1452 if (nargin < 3)
1453 iStudies = [];
1454 else
1455 iStudies = varargin{3};
1456 end
1457 % Look for surface file in all the surfaces of all subjects
1458 [argout1, argout2, argout3] = findFileInStudies('HeadModel', 'FileName', HeadModelFile, iStudies);
1459
1460 %% ==== NOISECOV FILE ====
1461 % Usage: [sStudy, iStudy, iNoiseCov] = bst_get('NoiseCovFile', NoiseCovFile, iStudies)
1462 % [sStudy, iStudy, iNoiseCov] = bst_get('NoiseCovFile', NoiseCovFile)
1463 % Usage: [sStudy, iStudy, iNoiseCov] = bst_get('DataCovFile', NoiseCovFile, iStudies)
1464 % [sStudy, iStudy, iNoiseCov] = bst_get('DataCovFile', NoiseCovFile)
1465 case {'NoiseCovFile', 'DataCovFile'}
1466 % No protocol in database
1467 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1468 return;
1469 end
1470 % Input #2: NoiseCovFile
1471 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1472 NoiseCovFile = varargin{2};
1473 NoiseCovFile = strrep(NoiseCovFile, ProtocolInfo.STUDIES, '');
1474 % Input #3: iStudies
1475 if (nargin < 3)
1476 iStudies = [];
1477 else
1478 iStudies = varargin{3};
1479 end
1480 % Look for surface file in all the surfaces of all subjects
1481 [argout1, argout2, argout3] = findFileInStudies('NoiseCov', 'FileName', NoiseCovFile, iStudies);
1482
1483
1484 %% ==== DATA FILE ====
1485 % Usage: [sStudy, iStudy, iData] = bst_get('DataFile', DataFile, iStudies)
1486 % [sStudy, iStudy, iData] = bst_get('DataFile', DataFile)
1487 case 'DataFile'
1488 % No protocol in database
1489 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1490 return;
1491 end
1492 % Input #2: DataFile
1493 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1494 DataFile = varargin{2};
1495 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1496 % Input #3: iStudies
1497 if (nargin < 3)
1498 iStudies = [];
1499 else
1500 iStudies = varargin{3};
1501 end
1502 % Look for file in all the studies
1503 [argout1, argout2, argout3] = findFileInStudies('Data', 'FileName', DataFile, iStudies);
1504
1505
1506 %% ==== DATA FOR DATA LIST ====
1507 % Usage: [iFoundData] = bst_get('DataForDataList', iStudy, DataListName)
1508 case 'DataForDataList'
1509 iStudy = varargin{2};
1510 DataListName = varargin{3};
1511 % Get study structure
1512 sStudy = bst_get('Study', iStudy);
1513 % Get all the data files held by this datalist
1514 listComments = cellfun(@(c)deblank(str_remove_parenth(c)), {sStudy.Data.Comment}, 'UniformOutput', 0);
1515 iFoundData = find(strcmp(listComments, DataListName));
1516 % Return found data files
1517 argout1 = iFoundData;
1518
1519 %% ==== MATRIX FOR MATRIX LIST ====
1520 % Usage: [iFoundMatrix] = bst_get('MatrixForMatrixList', iStudy, MatrixListName)
1521 case 'MatrixForMatrixList'
1522 iStudy = varargin{2};
1523 MatrixListName = varargin{3};
1524 % Get study structure
1525 sStudy = bst_get('Study', iStudy);
1526 % Get all the matrix files held by this datalist
1527 listComments = cellfun(@(c)deblank(str_remove_parenth(c)), {sStudy.Matrix.Comment}, 'UniformOutput', 0);
1528 iFoundMatrix = find(strcmp(listComments, MatrixListName));
1529 % Return found matrix files
1530 argout1 = iFoundMatrix;
1531
1532
1533 %% ==== DATA FOR STUDY (INCLUDING SHARED STUDIES) ====
1534 % Usage: [iStudies, iDatas] = bst_get('DataForStudy', iStudy)
1535 case 'DataForStudy'
1536 % Get target study
1537 iStudy = varargin{2};
1538 sStudy = bst_get('Study', iStudy);
1539 isDefaultStudy = strcmpi(sStudy.Name, bst_get('DirDefaultStudy'));
1540 isGlobalDefault = (iStudy == -3);
1541
1542 % If study is the global default study
1543 sStudies = [];
1544 iStudies = [];
1545 if isGlobalDefault
1546 % Get all the subjects of the protocol
1547 nbSubjects = bst_get('SubjectCount');
1548 for iSubject = 1:nbSubjects
1549 sSubject = bst_get('Subject', iSubject, 1);
1550 if sSubject.UseDefaultChannel
1551 [tmp_sStudies, tmp_iStudies] = bst_get('StudyWithSubject', sSubject.FileName);
1552 sStudies = [sStudies, tmp_sStudies];
1553 iStudies = [iStudies, tmp_iStudies];
1554 end
1555 end
1556 % Else, if study is a subject's default study (ie. channel file is shared by all studies of one subject)
1557 elseif isDefaultStudy
1558 % Get all the subject's studies
1559 [sStudies, iStudies] = bst_get('StudyWithSubject', sStudy.BrainStormSubject, 'intra_subject', 'default_study');
1560 else
1561 % Normal: one channel per condition
1562 sStudies = sStudy;
1563 iStudies = iStudy;
1564 end
1565 % Get all the DataFiles for all these studies
1566 for i = 1:length(sStudies)
1567 nData = length(sStudies(i).Data);
1568 argout1 = [argout1, repmat(iStudies(i), [1,nData])];
1569 argout2 = [argout2, 1:nData];
1570 end
1571
1572
1573 %% ==== DATA FOR STUDIES (INCLUDING SHARED STUDIES) ====
1574 % Usage: [iStudies, iDatas] = bst_get('DataForStudies', iStudies)
1575 case 'DataForStudies'
1576 iStudies = varargin{2};
1577 for i = 1:length(iStudies)
1578 [tmp_iStudies, tmp_iDatas] = bst_get('DataForStudy', iStudies(i));
1579 argout1 = [argout1, tmp_iStudies];
1580 argout2 = [argout2, tmp_iDatas];
1581 end
1582
1583 %% ==== DATA FILE FOR CHANNEL FILE ====
1584 % Usage: DataFiles = bst_get('DataForChannelFile', ChannelFile)
1585 case 'DataForChannelFile'
1586 ChannelFile = varargin{2};
1587 DataFiles = {};
1588 % Get study for the given channel file
1589 [sStudy, iStudy] = bst_get('ChannelFile', ChannelFile);
1590 if isempty(sStudy)
1591 return;
1592 end
1593 % Get dependent data files
1594 [iStudies, iDatas] = bst_get('DataForStudy', iStudy);
1595 % Get all the Data filenames
1596 for i = 1:length(iStudies)
1597 sStudy = bst_get('Study', iStudies(i));
1598 DataFiles = cat(2, DataFiles, {sStudy.Data(iDatas(i)).FileName});
1599 end
1600 argout1 = DataFiles;
1601
1602
1603 %% ==== RESULTS FILE ====
1604 % Usage: [sStudy, iStudy, iResult] = bst_get('ResultsFile', ResultsFile, iStudies)
1605 % [sStudy, iStudy, iResult] = bst_get('ResultsFile', ResultsFile)
1606 case 'ResultsFile'
1607 % No protocol in database
1608 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1609 return;
1610 end
1611 % Input #2: ResultsFile
1612 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1613 ResultsFile = varargin{2};
1614 ResultsFile = strrep(ResultsFile, ProtocolInfo.STUDIES, '');
1615 % Input #3: iStudies
1616 if (nargin < 3)
1617 iStudies = [];
1618 else
1619 iStudies = varargin{3};
1620 end
1621 % Look for surface file in all the surfaces of all subjects
1622 [argout1, argout2, argout3] = findFileInStudies('Result', 'FileName', ResultsFile, iStudies);
1623
1624
1625 %% ==== RESULTS FOR DATA FILE ====
1626 % Usage: [sStudy, iStudy, iResults] = bst_get('ResultsForDataFile', DataFile) : search the whole protocol
1627 % Usage: [sStudy, iStudy, iResults] = bst_get('ResultsForDataFile', DataFile, iStudies) : search only the specified studies
1628 case 'ResultsForDataFile'
1629 % No protocol in database
1630 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1631 return;
1632 end
1633 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1634 % Input #2: DataFile
1635 DataFile = varargin{2};
1636 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1637 % Determine in which studies to search for ResultsFile
1638 if (nargin >= 3)
1639 % Studies specified in argument
1640 iStudy = varargin{3};
1641 else
1642 % Get study in which DataFile is located
1643 [sStudy, iStudy] = bst_get('DataFile', DataFile);
1644 if isempty(iStudy)
1645 return;
1646 end
1647 end
1648 % Search selected studies
1649 [argout1, argout2, argout3] = findFileInStudies('Result', 'DataFile', DataFile, iStudy);
1650
1651
1652 %% ==== STAT FILE ====
1653 % Usage: [sStudy, iStudy, iData] = bst_get('StatFile', StatFile, iStudies)
1654 % [sStudy, iStudy, iData] = bst_get('StatFile', StatFile)
1655 case 'StatFile'
1656 % No protocol in database
1657 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1658 return;
1659 end
1660 % Input #2: SataFile
1661 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1662 StatFile = varargin{2};
1663 StatFile = strrep(StatFile, ProtocolInfo.STUDIES, '');
1664 % Input #3: iStudies
1665 if (nargin < 3)
1666 iStudies = [];
1667 else
1668 iStudies = varargin{3};
1669 end
1670 % Look for surface file in all the surfaces of all subjects
1671 [argout1, argout2, argout3] = findFileInStudies('Stat', 'FileName', StatFile, iStudies);
1672
1673
1674 %% ==== STAT FOR DATA FILE ====
1675 % Usage: [sStudy, iStudy, iResults] = bst_get('StatForDataFile', DataFile) : search the whole protocol
1676 % Usage: [sStudy, iStudy, iResults] = bst_get('StatForDataFile', DataFile, iStudies) : search only the specified studies
1677 case 'StatForDataFile'
1678 % No protocol in database
1679 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1680 return;
1681 end
1682 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1683 % Parse inputs
1684 if (nargin >= 2)
1685 DataFile = varargin{2};
1686 DataFile = strrep(DataFile, ProtocolInfo.STUDIES, '');
1687 else
1688 error('Invalid call to bst_get().');
1689 end
1690 % Determine in which studies to search for ResultsFile
1691 if (nargin >= 3)
1692 % Studies specified in argument
1693 iStudies = varargin{3};
1694 else
1695 % Get study in which DataFile is located
1696 [sStudies, iStudies] = bst_get('DataFile', DataFile);
1697 if isempty(iStudies)
1698 return;
1699 end
1700 end
1701 % Search selected studies
1702 [argout1, argout2, argout3] = findFileInStudies('Stat', 'DataFile', DataFile, iStudies);
1703
1704 %% ==== TIMEFREQ FILE ====
1705 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqFile', TimefreqFile, iStudies)
1706 % [sStudy, iStudy, iTimefreq] = bst_get('TimefreqFile', TimefreqFile)
1707 case 'TimefreqFile'
1708 % No protocol in database
1709 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1710 return;
1711 end
1712 % Input #2: TimefreqFile
1713 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1714 TimefreqFile = varargin{2};
1715 TimefreqFile = strrep(TimefreqFile, ProtocolInfo.STUDIES, '');
1716 % Remove optional RefRowName
1717 iPipe = find(TimefreqFile == '|', 1);
1718 if ~isempty(iPipe)
1719 TimefreqFile = TimefreqFile(1:iPipe-1);
1720 end
1721 % Input #3: iStudies
1722 if (nargin < 3)
1723 iStudies = [];
1724 else
1725 iStudies = varargin{3};
1726 end
1727 % Look for surface file in all the surfaces of all subjects
1728 [argout1, argout2, argout3] = findFileInStudies('Timefreq', 'FileName', TimefreqFile, iStudies);
1729
1730 %% ==== TIMEFREQ FOR FILE ====
1731 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForFile', FileName, iStudies) : search only the specified studies
1732 % [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForFile', FileName) : search the whole protocol
1733 case 'TimefreqForFile'
1734 % No protocol in database
1735 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1736 return;
1737 end
1738 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1739 % Parse inputs
1740 if (nargin >= 2)
1741 FileName = varargin{2};
1742 FileName = strrep(FileName, ProtocolInfo.STUDIES, '');
1743 else
1744 error('Invalid call to bst_get().');
1745 end
1746 % Get study in which file is located
1747 if (nargin >= 3)
1748 iStudies = varargin{3};
1749 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName, iStudies);
1750 else
1751 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName);
1752 end
1753 % If file was not found
1754 if isempty(iStudy)
1755 return;
1756 end
1757 % Search direct dependent files
1758 [tmp, tmp, iTf] = findFileInStudies('Timefreq', 'DataFile', FileName, iStudy);
1759 % Data files: get all the depending results, and then all the timefreq for those results
1760 if strcmpi(DataType, 'data')
1761 [tmp, tmp, iResults] = bst_get('ResultsForDataFile', FileName, iStudy);
1762 for i = 1:length(iResults);
1763 % Search selected studies
1764 [tmp, tmp, iTfRes] = findFileInStudies('Timefreq', 'DataFile', sStudy.Result(iResults(i)).FileName, iStudy);
1765 if ~isempty(iTfRes)
1766 iTf = [iTf iTfRes];
1767 end
1768 end
1769 end
1770 % Return results
1771 if ~isempty(iTf)
1772 argout1 = sStudy;
1773 argout2 = iStudy;
1774 argout3 = iTf;
1775 end
1776
1777
1778 %% ==== DIPOLES FOR FILE ====
1779 % Usage: [sStudy, iStudy, iDipoles] = bst_get('DipolesForFile', FileName, iStudies) : search only the specified studies
1780 % [sStudy, iStudy, iDipoles] = bst_get('DipolesForFile', FileName) : search the whole protocol
1781 case 'DipolesForFile'
1782 % No protocol in database
1783 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1784 return;
1785 end
1786 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1787 % Parse inputs
1788 if (nargin >= 2)
1789 FileName = varargin{2};
1790 FileName = strrep(FileName, ProtocolInfo.STUDIES, '');
1791 else
1792 error('Invalid call to bst_get().');
1793 end
1794 % Get study in which file is located
1795 if (nargin >= 3)
1796 iStudies = varargin{3};
1797 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName, iStudies);
1798 else
1799 [sStudy, iStudy, iFile, DataType] = bst_get('AnyFile', FileName);
1800 end
1801 % If file was not found
1802 if isempty(iStudy)
1803 return;
1804 end
1805 % Search direct dependent files
1806 [tmp, tmp, iDip] = findFileInStudies('Dipoles', 'DataFile', FileName, iStudy);
1807 % Data files: get all the depending results, and then all the timefreq for those results
1808 if strcmpi(DataType, 'data')
1809 [tmp, tmp, iResults] = bst_get('ResultsForDataFile', FileName, iStudy);
1810 for i = 1:length(iResults);
1811 % Search selected studies
1812 [tmp, tmp, iDipRes] = findFileInStudies('Dipoles', 'DataFile', sStudy.Result(iResults(i)).FileName, iStudy);
1813 if ~isempty(iDipRes)
1814 iDip = [iDip, iDipRes];
1815 end
1816 end
1817 end
1818 % Return results
1819 if ~isempty(iDip)
1820 argout1 = sStudy;
1821 argout2 = iStudy;
1822 argout3 = iDip;
1823 end
1824
1825
1826 %% ==== TIMEFREQ FOR KERNEL ====
1827 % Find all the timefreq files dependent from links due to a given kernel
1828 % Usage: [sStudy, iStudy, iTimefreq] = bst_get('TimefreqForKernel', KernelFile)
1829 case 'TimefreqForKernel'
1830 sFoundStudy = [];
1831 iFoundStudy = [];
1832 iFoundTimefreq = [];
1833 % No protocol in database
1834 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1835 return;
1836 end
1837 % Get study in which file is located
1838 KernelFile = varargin{2};
1839 [sStudy, iStudy, iFile, DataType] = bst_get('ResultsFile', KernelFile);
1840 if isempty(iStudy)
1841 return;
1842 end
1843 % Get all the data files relative with this kernel
1844 [iDepStudies, iDepDatas] = bst_get('DataForStudy', iStudy);
1845 % Keep only once each study
1846 iDepStudies = unique(iDepStudies);
1847 % Process all the dependent studies
1848 for iSt = 1:length(iDepStudies)
1849 % Get the study structure
1850 sDepStudy = bst_get('Study', iDepStudies(iSt));
1851 % Process each timefreq file separately
1852 for iTf = 1:length(sDepStudy.Timefreq)
1853 DataFile = sDepStudy.Timefreq(iTf).DataFile;
1854 % Keep only the files that are linked to LINKS
1855 if isempty(DataFile) || (length(DataFile) < 5) || ~isequal(DataFile(1:5), 'link|')
1856 continue;
1857 end
1858 % Split link
1859 splitFile = str_split(DataFile, '|');
1860 % If the kernel is found: add it to the found list
1861 if file_compare(splitFile{2}, KernelFile)
1862 sFoundStudy = [sFoundStudy sDepStudy];
1863 iFoundStudy = [iFoundStudy, iDepStudies(iSt)];
1864 iFoundTimefreq = [iFoundTimefreq, iTf];
1865 end
1866 end
1867 end
1868 % Return findings
1869 argout1 = sFoundStudy;
1870 argout2 = iFoundStudy;
1871 argout3 = iFoundTimefreq;
1872
1873
1874 %% ==== DIPOLES FOR KERNEL ====
1875 % Find all the dipoles files dependent from links due to a given kernel
1876 % Usage: [sStudy, iStudy, iDipoles] = bst_get('TimefreqForKernel', KernelFile)
1877 case 'DipolesForKernel'
1878 sFoundStudy = [];
1879 iFoundStudy = [];
1880 iFoundDipoles = [];
1881 % No protocol in database
1882 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1883 return;
1884 end
1885 % Get study in which file is located
1886 KernelFile = varargin{2};
1887 [sStudy, iStudy, iFile, DataType] = bst_get('ResultsFile', KernelFile);
1888 if isempty(iStudy)
1889 return;
1890 end
1891 % Get all the data files relative with this kernel
1892 [iDepStudies, iDepDatas] = bst_get('DataForStudy', iStudy);
1893 % Keep only once each study
1894 iDepStudies = unique(iDepStudies);
1895 % Process all the dependent studies
1896 for iSt = 1:length(iDepStudies)
1897 % Get the study structure
1898 sDepStudy = bst_get('Study', iDepStudies(iSt));
1899 % Process each timefreq file separately
1900 for iDip = 1:length(sDepStudy.Dipoles)
1901 DataFile = sDepStudy.Dipoles(iDip).DataFile;
1902 % Keep only the files that are linked to LINKS
1903 if isempty(DataFile) || (length(DataFile) < 5) || ~isequal(DataFile(1:5), 'link|')
1904 continue;
1905 end
1906 % Split link
1907 splitFile = str_split(DataFile, '|');
1908 % If the kernel is found: add it to the found list
1909 if file_compare(splitFile{2}, KernelFile)
1910 sFoundStudy = [sFoundStudy sDepStudy];
1911 iFoundStudy = [iFoundStudy, iDepStudies(iSt)];
1912 iFoundDipoles = [iFoundDipoles, iDip];
1913 end
1914 end
1915 end
1916 % Return findings
1917 argout1 = sFoundStudy;
1918 argout2 = iFoundStudy;
1919 argout3 = iFoundDipoles;
1920
1921
1922 %% ==== DIPOLES FILE ====
1923 % Usage: [sStudy, iStudy, iDipole] = bst_get('DipolesFile', DipolesFile, iStudies)
1924 % [sStudy, iStudy, iDipole] = bst_get('DipolesFile', DipolesFile)
1925 case 'DipolesFile'
1926 % No protocol in database
1927 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1928 return;
1929 end
1930 % Input #2: DipolesFile
1931 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1932 DipolesFile = varargin{2};
1933 DipolesFile = strrep(DipolesFile, ProtocolInfo.STUDIES, '');
1934 % Input #3: iStudies
1935 if (nargin < 3)
1936 iStudies = [];
1937 else
1938 iStudies = varargin{3};
1939 end
1940 % Look for surface file in all the surfaces of all subjects
1941 [argout1, argout2, argout3] = findFileInStudies('Dipoles', 'FileName', DipolesFile, iStudies);
1942
1943
1944 %% ==== MATRIX FILE ====
1945 % Usage: [sStudy, iStudy, iDipole] = bst_get('MatrixFile', MatrixFile, iStudies)
1946 % [sStudy, iStudy, iDipole] = bst_get('MatrixFile', MatrixFile)
1947 case 'MatrixFile'
1948 % No protocol in database
1949 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1950 return;
1951 end
1952 % Input #2: MatrixFile
1953 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1954 MatrixFile = varargin{2};
1955 MatrixFile = strrep(MatrixFile, ProtocolInfo.STUDIES, '');
1956 % Input #3: iStudies
1957 if (nargin < 3)
1958 iStudies = [];
1959 else
1960 iStudies = varargin{3};
1961 end
1962 % Look for surface file in all the surfaces of all subjects
1963 [argout1, argout2, argout3] = findFileInStudies('Matrix', 'FileName', MatrixFile, iStudies);
1964
1965 %% ==== IMAGE FILE ====
1966 % Usage: [sStudy, iStudy, iDipole] = bst_get('ImageFile', ImageFile, iStudies)
1967 % [sStudy, iStudy, iDipole] = bst_get('ImageFile', ImageFile)
1968 case 'ImageFile'
1969 % No protocol in database
1970 if isempty(GlobalData.DataBase.iProtocol) || (GlobalData.DataBase.iProtocol == 0)
1971 return;
1972 end
1973 % Input #2: ImageFile
1974 ProtocolInfo = GlobalData.DataBase.ProtocolInfo(GlobalData.DataBase.iProtocol);
1975 ImageFile = varargin{2};
1976 ImageFile = strrep(ImageFile, ProtocolInfo.STUDIES, '');
1977 % Input #3: iStudies
1978 if (nargin < 3)
1979 iStudies = [];
1980 else
1981 iStudies = varargin{3};
1982 end
1983 % Look for surface file in all the surfaces of all subjects
1984 [argout1, argout2, argout3] = findFileInStudies('Image', 'FileName', ImageFile, iStudies);
1985
1986
1987 %% ==== ANY FILE ====
1988 % Usage: [sStudy, iStudy, iFile, DataType, sItem] = bst_get('AnyFile', FileName, iStudies)
1989 % [sStudy, iStudy, iFile, DataType, sItem] = bst_get('AnyFile', FileName)
1990 case 'AnyFile'
1991 % Input #2: FileName
1992 FileName = varargin{2};
1993 if isempty(FileName)
1994 return
1995 end
1996 % Input #3: iStudies
1997 if (nargin < 3)
1998 iStudies = [];
1999 else
2000 iStudies = varargin{3};
2001 end
2002 % Get data format
2003 fileType = file_gettype(FileName);
2004 if isempty(fileType)
2005 error('File type is not recognized.');
2006 end
2007 sItem = [];
2008 % Get information related with this file
2009 switch (fileType)
2010 % ===== FUNCTIONAL =====
2011 case 'channel'
2012 [sStudy, iStudy] = bst_get('ChannelFile', FileName);
2013 iItem = 1;
2014 if (nargout >= 5) && ~isempty(sStudy)
2015 sItem = sStudy.Channel;
2016 end
2017 case 'headmodel'
2018 [sStudy, iStudy, iItem] = bst_get('HeadModelFile', FileName);
2019 if (nargout >= 5) && ~isempty(sStudy)
2020 sItem = sStudy.HeadModel(iItem);
2021 end
2022 case 'noisecov'
2023 [sStudy, iStudy, iItem] = bst_get('NoiseCovFile', FileName);
2024 if (nargout >= 5) && ~isempty(sStudy)
2025 sItem = sStudy.NoiseCov(iItem);
2026 end
2027 case 'ndatacov'
2028 [sStudy, iStudy, iItem] = bst_get('DataCovFile', FileName);
2029 if (nargout >= 5) && ~isempty(sStudy)
2030 sItem = sStudy.NoiseCov(iItem);
2031 end
2032 case {'data', 'spike'}
2033 [sStudy, iStudy, iItem] = bst_get('DataFile', FileName, iStudies);
2034 if (nargout >= 5) && ~isempty(sStudy)
2035 sItem = sStudy.Data(iItem);
2036 end
2037 case {'results', 'link'}
2038 [sStudy, iStudy, iItem] = bst_get('ResultsFile', FileName, iStudies);
2039 if (nargout >= 5) && ~isempty(sStudy)
2040 sItem = sStudy.Result(iItem);
2041 end
2042 case {'presults', 'pdata','ptimefreq','pmatrix'}
2043 [sStudy, iStudy, iItem] = bst_get('StatFile', FileName, iStudies);
2044 if (nargout >= 5) && ~isempty(sStudy)
2045 sItem = sStudy.Stat(iItem);
2046 end
2047 case 'dipoles'
2048 [sStudy, iStudy, iItem] = bst_get('DipolesFile', FileName, iStudies);
2049 if (nargout >= 5) && ~isempty(sStudy)
2050 sItem = sStudy.Dipoles(iItem);
2051 end
2052 case 'timefreq'
2053 % Remove optional RefRowName
2054 iPipe = find(FileName == '|', 1);
2055 if ~isempty(iPipe)
2056 FileName = FileName(1:iPipe-1);
2057 end
2058 [sStudy, iStudy, iItem] = bst_get('TimefreqFile', FileName, iStudies);
2059 if (nargout >= 5) && ~isempty(sStudy)
2060 sItem = sStudy.Timefreq(iItem);
2061 end
2062 case 'matrix'
2063 [sStudy, iStudy, iItem] = bst_get('MatrixFile', FileName, iStudies);
2064 if (nargout >= 5) && ~isempty(sStudy)
2065 sItem = sStudy.Matrix(iItem);
2066 end
2067 case 'brainstormstudy'
2068 [sStudy, iStudy] = bst_get('Study', FileName);
2069 iItem = 0;
2070 if (nargout >= 5) && ~isempty(sStudy)
2071 sItem = sStudy;
2072 end
2073 case {'image', 'video', 'videolink'}
2074 [sStudy, iStudy, iItem] = bst_get('ImageFile', FileName, iStudies);
2075 if (nargout >= 5) && ~isempty(sStudy)
2076 sItem = sStudy.Image(iItem);
2077 end
2078 % ===== ANATOMY =====
2079 case {'cortex','scalp','innerskull','outerskull','tess','fibers','fem'}
2080 [sStudy, iStudy, iItem] = bst_get('SurfaceFile', FileName);
2081 if (nargout >= 5) && ~isempty(sStudy)
2082 sItem = sStudy.Surface(iItem);
2083 end
2084 case 'subjectimage'
2085 [sStudy, iStudy, iItem] = bst_get('MriFile', FileName);
2086 if (nargout >= 5) && ~isempty(sStudy)
2087 sItem = sStudy.Anatomy(iItem);
2088 end
2089 case 'brainstormsubject'
2090 [sStudy, iStudy] = bst_get('Subject', FileName);
2091 iItem = 0;
2092 if (nargout >= 5) && ~isempty(sStudy)
2093 sItem = sStudy;
2094 end
2095 otherwise
2096 error('File type is not recognized.');
2097 end
2098 argout1 = sStudy;
2099 argout2 = iStudy;
2100 argout3 = iItem;
2101 argout4 = fileType;
2102 if (nargout >= 5)
2103 argout5 = sItem;
2104 end
2105
2106
2107 %% ==== GET RELATED DATA FILE ====
2108 % Usage: DataFile = bst_get('RelatedDataFile', FileName, iStudies)
2109 % DataFile = bst_get('RelatedDataFile', FileName)
2110 case 'RelatedDataFile'
2111 % Input #2: FileName
2112 FileName = varargin{2};
2113 % Input #3: iStudies
2114 if (nargin < 3)
2115 iStudies = [];
2116 else
2117 iStudies = varargin{3};
2118 end
2119 % Get file in database
2120 [sStudy, iStudy, iFile, fileType] = bst_get('AnyFile', FileName, iStudies);
2121 % If this data file does not belong to any study
2122 if isempty(sStudy)
2123 return;
2124 end
2125 % Get associated data file
2126 switch (fileType)
2127 case 'data'
2128 RelatedDataFile = sStudy.Data(iFile).FileName;
2129 case {'pdata','presults','ptimefreq','pmatrix'}
2130 RelatedDataFile = sStudy.Stat(iFile).DataFile;
2131 case {'results', 'link'}
2132 RelatedDataFile = sStudy.Result(iFile).DataFile;
2133 case 'dipoles'
2134 RelatedDataFile = sStudy.Dipoles(iFile).DataFile;
2135 case 'timefreq'
2136 RelatedDataFile = sStudy.Timefreq(iFile).DataFile;
2137 otherwise
2138 RelatedDataFile = '';
2139 end
2140 % If related file is results: get related data file
2141 if ~isempty(RelatedDataFile)
2142 relFileType = file_gettype(RelatedDataFile);
2143 if ismember(relFileType, {'link','results'})
2144 RelatedDataFile = bst_get('RelatedDataFile', RelatedDataFile, iStudy);
2145 end
2146 end
2147 % Return file
2148 argout1 = RelatedDataFile;
2149
2150 %% ==== ALL CONDITIONS FOR ONE SUBJECT ====
2151 % Usage: [Conditions] = bst_get('ConditionsForSubject', SubjectFile)
2152 case 'ConditionsForSubject'
2153 % Parse inputs
2154 if (nargin == 2)
2155 SubjectFile = varargin{2};
2156 else
2157 error('Invalid call to bst_get().');
2158 end
2159 % Get list of studies associated with subject
2160 sStudies = bst_get('StudyWithSubject', SubjectFile);
2161 % Get Conditions for each study
2162 Conditions = {};
2163 for i = 1:length(sStudies)
2164 % Test if the condition of this study was not added previously
2165 isNewCondition = 1;
2166 for iCond = 1:length(Conditions)
2167 % If new condition is found
2168 % (and excludes DirAnalysisIntra and DirDefaultSubject from list)
2169 if isempty(sStudies(i).Condition) || ...
2170 isequal(sStudies(i).Condition, Conditions(iCond)) || ...
2171 strcmpi(sStudies(i).Condition{1}, bst_get('DirAnalysisIntra')) || ...
2172 strcmpi(sStudies(i).Condition{1}, bst_get('DirDefaultSubject'))
2173 isNewCondition = 0;
2174 break;
2175 end
2176 end
2177 % If Condition is not added yet : add it to the list
2178 if isNewCondition && ~isempty(sStudies(i).Condition)
2179 Conditions{end+1} = sStudies(i).Condition{1};
2180 end
2181 end
2182 % Return conditions list
2183 argout1 = Conditions;
2184
2185
2186 %% ==== ANATOMY DEFAULTS ====
2187 % Returns the list of all the anatomy defaults (distributed with the software + user defined)
2188 case 'AnatomyDefaults'
2189 % Parse inputs
2190 if (nargin == 2)
2191 AnatName = varargin{2};
2192 else
2193 AnatName = [];
2194 end
2195 % Get templates from the brainstorm3 folder
2196 progDir = bst_fullfile(bst_get('BrainstormDefaultsDir'), 'anatomy');
2197 progFiles = dir(progDir);
2198 % Get templates from the user folder
2199 userDir = bst_fullfile(bst_get('UserDefaultsDir'), 'anatomy');
2200 userFiles = dir(userDir);
2201 % Combine the two lists
2202 AllProgNames = cat(2, {progFiles.name}, cellfun(@(c)cat(2,c,'.zip'), {progFiles.name}, 'UniformOutput', 0));
2203 AllFiles = cat(2, cellfun(@(c)bst_fullfile(progDir,c), setdiff({progFiles.name}, {'.','..'}), 'UniformOutput', 0), ...
2204 cellfun(@(c)bst_fullfile(userDir,c), setdiff({userFiles.name}, AllProgNames), 'UniformOutput', 0));
2205 % Initialize list of defaults
2206 sTemplates = repmat(struct('FilePath',[],'Name',[]), 0);
2207 % Find all the valid defaults (.zip files or subdirectory with a brainstormsubject.mat in it)
2208 for i = 1:length(AllFiles)
2209 % Decompose file name
2210 [fPath, fBase, fExt] = bst_fileparts(AllFiles{i});
2211 % Entry is a directory W/ a name that does not start with a '.'
2212 if isempty(fBase) || strcmpi(fBase(1),'.') || (~isempty(fExt) && ~strcmpi(fExt, '.zip'))
2213 continue;
2214 end
2215 % If it's a folder: check for a brainstormsubject file
2216 if isdir(AllFiles{i})
2217 bstFiles = dir(bst_fullfile(AllFiles{i}, 'brainstormsubject*.mat'));
2218 if (length(bstFiles) == 1)
2219 sTemplates(end+1).FilePath = AllFiles{i};
2220 sTemplates(end).Name = fBase;
2221 end
2222 % If it's a zip file
2223 elseif isequal(fExt, '.zip')
2224 sTemplates(end+1).FilePath = AllFiles{i};
2225 sTemplates(end).Name = fBase;
2226 end
2227 end
2228 % Get defaults from internet
2229 if ~ismember('icbm152', lower({sTemplates.Name}))
2230 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_2019';
2231 sTemplates(end).Name = 'ICBM152';
2232 end
2233 if ~ismember('icbm152_2019', lower({sTemplates.Name}))
2234 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_2019';
2235 sTemplates(end).Name = 'ICBM152_2019';
2236 end
2237 if ~ismember('icbm152_brainsuite_2016', lower({sTemplates.Name}))
2238 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=ICBM152_BrainSuite_2016';
2239 sTemplates(end).Name = 'ICBM152_BrainSuite_2016';
2240 end
2241 if ~ismember('colin27_2016', lower({sTemplates.Name}))
2242 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Colin27_2016';
2243 sTemplates(end).Name = 'Colin27_2016';
2244 end
2245 if ~ismember('colin27_brainsuite_2016', lower({sTemplates.Name}))
2246 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Colin27_BrainSuite_2016';
2247 sTemplates(end).Name = 'Colin27_BrainSuite_2016';
2248 end
2249 if ~ismember('bci-dni_brainsuite_2020', lower({sTemplates.Name}))
2250 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=BCI-DNI_BrainSuite_2020';
2251 sTemplates(end).Name = 'BCI-DNI_BrainSuite_2020';
2252 end
2253 if ~ismember('uscbrain_brainsuite_2020', lower({sTemplates.Name}))
2254 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=USCBrain_BrainSuite_2020';
2255 sTemplates(end).Name = 'USCBrain_BrainSuite_2020';
2256 end
2257 if ~ismember('fsaverage_2020', lower({sTemplates.Name}))
2258 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=FSAverage_2020';
2259 sTemplates(end).Name = 'FsAverage_2020';
2260 end
2261 if ~ismember('kabdebon_7w', lower({sTemplates.Name}))
2262 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Kabdebon_7w';
2263 sTemplates(end).Name = 'Kabdebon_7w';
2264 end
2265 if ~ismember('oreilly_0.5m_2021', lower({sTemplates.Name}))
2266 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_0.5m_2021';
2267 sTemplates(end).Name = 'Oreilly_0.5m_2021';
2268 end
2269 if ~ismember('oreilly_1m_2021', lower({sTemplates.Name}))
2270 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_1m_2021';
2271 sTemplates(end).Name = 'Oreilly_1m_2021';
2272 end
2273 if ~ismember('oreilly_2m_2021', lower({sTemplates.Name}))
2274 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_2m_2021';
2275 sTemplates(end).Name = 'Oreilly_2m_2021';
2276 end
2277 if ~ismember(lower({sTemplates.Name}), 'oreilly_3m_2021')
2278 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_3m_2021';
2279 sTemplates(end).Name = 'Oreilly_3m_2021';
2280 end
2281 if ~ismember('oreilly_4.5m_2021', lower({sTemplates.Name}))
2282 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_4.5m_2021';
2283 sTemplates(end).Name = 'Oreilly_4.5m_2021';
2284 end
2285 if ~ismember('oreilly_6m_2021', lower({sTemplates.Name}))
2286 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_6m_2021';
2287 sTemplates(end).Name = 'Oreilly_6m_2021';
2288 end
2289 if ~ismember('oreilly_7.5m_2021', lower({sTemplates.Name}))
2290 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_7.5m_2021';
2291 sTemplates(end).Name = 'Oreilly_7.5m_2021';
2292 end
2293 if ~ismember('oreilly_9m_2021', lower({sTemplates.Name}))
2294 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_9m_2021';
2295 sTemplates(end).Name = 'Oreilly_9m_2021';
2296 end
2297 if ~ismember('oreilly_10.5m_2021', lower({sTemplates.Name}))
2298 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_10.5m_2021';
2299 sTemplates(end).Name = 'Oreilly_10.5m_2021';
2300 end
2301 if ~ismember('oreilly_12m_2021', lower({sTemplates.Name}))
2302 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_12m_2021';
2303 sTemplates(end).Name = 'Oreilly_12m_2021';
2304 end
2305 if ~ismember('oreilly_15m_2021', lower({sTemplates.Name}))
2306 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_15m_2021';
2307 sTemplates(end).Name = 'Oreilly_15m_2021';
2308 end
2309 if ~ismember('oreilly_18m_2021', lower({sTemplates.Name}))
2310 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_18m_2021';
2311 sTemplates(end).Name = 'Oreilly_18m_2021';
2312 end
2313 if ~ismember('oreilly_24m_2021', lower({sTemplates.Name}))
2314 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=Oreilly_24m_2021';
2315 sTemplates(end).Name = 'Oreilly_24m_2021';
2316 end
2317 % If a specific template was requested
2318 if ~isempty(AnatName)
2319 iAnat = find(strcmpi({sTemplates.Name}, AnatName));
2320 sTemplates = sTemplates(iAnat);
2321 end
2322 % Sort in alphabetical order
2323 if ~isempty(sTemplates)
2324 [tmp__, I] = sort_nat({sTemplates(2:end).Name});
2325 sTemplates = sTemplates([1, I+1]);
2326 end
2327 % Return defaults list
2328 argout1 = sTemplates;
2329
2330
2331 %% ==== MNI ATLASES ====
2332 % Returns the list of all the available MNI atlases
2333 case 'MniAtlasDefaults'
2334 % Get templates from the brainstorm3 folder
2335 mniDir = bst_fullfile(bst_get('UserDefaultsDir'), 'mniatlas');
2336 mniFiles = dir(bst_fullfile(mniDir, '*.nii.gz'));
2337 mniFiles = cellfun(@(c)bst_fullfile(mniDir,c), {mniFiles.name}, 'UniformOutput', 0);
2338 % Initialize list of defaults
2339 sTemplates = repmat(struct('FilePath',[],'Name',[],'Info',[]), 0);
2340 % Find all the valid defaults (.zip files or subdirectory with a brainstormsubject.mat in it)
2341 for i = 1:length(mniFiles)
2342 % Decompose file name
2343 [fPath, fBase, fExt] = bst_fileparts(mniFiles{i});
2344 % Keep only files with .nii and .nii.gz extensions
2345 if ~isempty(fBase) && (fBase(1) ~= '.') && ~isempty(fExt) && strcmpi(fExt, '.gz')
2346 sTemplates(end+1).FilePath = mniFiles{i};
2347 sTemplates(end).Name = strrep(fBase, '.nii', '');
2348 sTemplates(end).Info = '';
2349 end
2350 end
2351 % Sort in alphabetical order
2352 if ~isempty(sTemplates)
2353 [tmp__, I] = sort_nat(lower({sTemplates.Name}));
2354 sTemplates = sTemplates(I);
2355 end
2356
2357 % Get defaults from internet
2358 if ~ismember('aal2', lower({sTemplates.Name}))
2359 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AAL2';
2360 sTemplates(end).Name = 'AAL2';
2361 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aal/';
2362 end
2363 if ~ismember('aal3', lower({sTemplates.Name}))
2364 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AAL3';
2365 sTemplates(end).Name = 'AAL3';
2366 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aal/';
2367 end
2368 if ~ismember('aicha', lower({sTemplates.Name}))
2369 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_AICHA';
2370 sTemplates(end).Name = 'AICHA';
2371 sTemplates(end).Info = 'https://www.gin.cnrs.fr/en/tools/aicha';
2372 end
2373 if ~ismember('brainnetome', lower({sTemplates.Name}))
2374 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brainnetome';
2375 sTemplates(end).Name = 'Brainnetome';
2376 sTemplates(end).Info = 'http://atlas.brainnetome.org/';
2377 end
2378 if ~ismember('brainnetome_leaddbs', lower({sTemplates.Name}))
2379 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brainnetome_leaddbs';
2380 sTemplates(end).Name = 'Brainnetome_leaddbs';
2381 sTemplates(end).Info = 'http://atlas.brainnetome.org/';
2382 end
2383 if ~ismember('brodmann', lower({sTemplates.Name}))
2384 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Brodmann';
2385 sTemplates(end).Name = 'Brodmann';
2386 sTemplates(end).Info = 'https://people.cas.sc.edu/rorden/mricro/lesion.html#brod';
2387 end
2388 if ~ismember('hammers83', lower({sTemplates.Name}))
2389 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Hammers';
2390 sTemplates(end).Name = 'Hammers';
2391 sTemplates(end).Info = 'http://brain-development.org/brain-atlases/adult-brain-atlases/';
2392 end
2393 if ~ismember('neuromorphometrics', lower({sTemplates.Name}))
2394 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Neuromorphometrics';
2395 sTemplates(end).Name = 'Neuromorphometrics';
2396 sTemplates(end).Info = 'https://search.kg.ebrains.eu/instances/Dataset/ef48c5e9-6b3c-4d5a-a9a9-e678fe10bdf6';
2397 end
2398 if ~ismember('julich-brain-v25', lower({sTemplates.Name}))
2399 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Julich-Brain-v25';
2400 sTemplates(end).Name = 'Julich-Brain-v25';
2401 sTemplates(end).Info = 'https://search.kg.ebrains.eu/instances/Dataset/ef48c5e9-6b3c-4d5a-a9a9-e678fe10bdf6';
2402 end
2403 if ~ismember('schaefer2018_100_7net', lower({sTemplates.Name}))
2404 sTemplates(end+1).FilePath = 'http://neuroimage.usc.edu/bst/getupdate.php?t=mni_Schaefer2018';
2405 sTemplates(end).Name = 'Schaefer2018';
2406 sTemplates(end).Info = 'https://github.com/ThomasYeoLab/CBIG/tree/master/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal';
2407 end
2408 % Return defaults list
2409 argout1 = sTemplates;
2410
2411
2412 %% ==== EEG DEFAULTS ====
2413 % Returns an array of struct(fullpath, name) of all the Brainstorm eeg nets defaults
2414 % Usage: EegDefaults = bst_get('EegDefaults')
2415 % EegDefaults = bst_get('EegDefaults', TemplateName=[], SetupName=[])
2416 case 'EegDefaults'
2417 % Parse inputs
2418 if (nargin >= 3)
2419 SetupName = varargin{3};
2420 else
2421 SetupName = [];
2422 end
2423 if (nargin >= 2)
2424 TemplateName = varargin{2};
2425 else
2426 TemplateName = [];
2427 end
2428 % Get templates from the brainstorm3 folder
2429 progDir = bst_fullfile(bst_get('BrainstormDefaultsDir'), 'eeg');
2430 progFiles = dir(bst_fullfile(progDir, '*'));
2431 % Get templates from the user folder
2432 userDir = bst_fullfile(bst_get('UserDefaultsDir'), 'eeg');
2433 userFiles = dir(bst_fullfile(userDir, '*'));
2434 % Combine the two lists
2435 dirList = cat(2, cellfun(@(c)bst_fullfile(progDir,c), {progFiles.name}, 'UniformOutput', 0), ...
2436 cellfun(@(c)bst_fullfile(userDir,c), setdiff({userFiles.name}, {progFiles.name}), 'UniformOutput', 0));
2437 % Initialize list of folders
2438 fullDefaultsList = repmat(struct('contents','', 'name',''), 0);
2439 % For each template directory
2440 for iDir = 1:length(dirList)
2441 % Decompose file name
2442 [fPath, fBase, fExt] = bst_fileparts(dirList{iDir});
2443 % Entry is a not a folder, or starts with a "."
2444 if ~isdir(dirList{iDir}) || isempty(fBase) || strcmpi(fBase(1),'.')
2445 continue;
2446 end
2447 % Skip if it is not the requested template
2448 if ~isempty(TemplateName) && ~strcmpi(fBase, TemplateName)
2449 continue;
2450 end
2451 % Get files list
2452 fileList = dir(bst_fullfile(dirList{iDir}, 'channel*.mat'));
2453 defaultsList = repmat(struct('fullpath','', 'name',''), 0);
2454 % Find all the valid defaults (channel files)
2455 for iFile = 1:length(fileList)
2456 [tmp__, baseName] = bst_fileparts(fileList(iFile).name);
2457 baseName = strrep(baseName, 'channel_', '');
2458 baseName = strrep(baseName, '_channel', '');
2459 baseName = strrep(baseName, '_', ' ');
2460 % Skip if it is not the requested template
2461 if ~isempty(SetupName) && ~strcmpi(baseName, SetupName)
2462 continue;
2463 end
2464 % Add to list of templates
2465 iNewDefault = length(defaultsList) + 1;
2466 defaultsList(iNewDefault).fullpath = bst_fullfile(dirList{iDir}, fileList(iFile).name);
2467 defaultsList(iNewDefault).name = baseName;
2468 end
2469 % Add files list to defaults list
2470 if ~isempty(defaultsList)
2471 fullDefaultsList(end + 1) = struct('contents', defaultsList, ...
2472 'name', fBase);
2473 end
2474 end
2475 % Return defaults list
2476 argout1 = fullDefaultsList;
2477
2478
2479 %% ==== GET FILENAMES ====
2480 case 'GetFilenames'
2481 iStudies = varargin{2};
2482 iItems = varargin{3};
2483 DataType = varargin{4};
2484 FileNames = cell(1, length(iStudies));
2485 argout1 = {};
2486 for i = 1:length(iStudies)
2487 % Get study definition
2488 sStudy = bst_get('Study', iStudies(i));
2489 if isempty(sStudy)
2490 continue;
2491 end
2492 % Recordings or sources
2493 switch (DataType)
2494 case 'data'
2495 if (iItems(i) > length(sStudy.Data))
2496 return;
2497 end
2498 FileNames{i} = sStudy.Data(iItems(i)).FileName;
2499 case 'results'
2500 if (iItems(i) > length(sStudy.Result))
2501 return;
2502 end
2503 FileNames{i} = sStudy.Result(iItems(i)).FileName;
2504 case 'timefreq'
2505 if (iItems(i) > length(sStudy.Timefreq))
2506 return;
2507 end
2508 FileNames{i} = sStudy.Timefreq(iItems(i)).FileName;
2509 case 'matrix'
2510 if (iItems(i) > length(sStudy.Matrix))
2511 return;
2512 end
2513 FileNames{i} = sStudy.Matrix(iItems(i)).FileName;
2514 case {'pdata','presults','ptimfreq'}
2515 if (iItems(i) > length(sStudy.Stat))
2516 return;
2517 end
2518 FileNames{i} = sStudy.Stat(iItems(i)).FileName;
2519 end
2520 end
2521 argout1 = FileNames;
2522
2523
2524 %% ==== GUI ====
2525 case 'BstFrame'
2526 if isempty(GlobalData) || isempty(GlobalData.Program.GUI) || isempty(GlobalData.Program.GUI.mainWindow)
2527 argout1 = [];
2528 else
2529 argout1 = GlobalData.Program.GUI.mainWindow.jBstFrame;
2530 end
2531 case 'BstControls'
2532 if isempty(GlobalData) || isempty(GlobalData.Program) || isempty(GlobalData.Program.GUI) || isempty(GlobalData.Program.GUI.mainWindow)
2533 argout1 = [];
2534 else
2535 argout1 = GlobalData.Program.GUI.mainWindow;
2536 end
2537 case 'isGUI'
2538 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'GuiLevel')
2539 argout1 = [];
2540 else
2541 argout1 = (GlobalData.Program.GuiLevel >= 1);
2542 end
2543 case 'GuiLevel'
2544 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'GuiLevel')
2545 argout1 = [];
2546 else
2547 argout1 = GlobalData.Program.GuiLevel;
2548 end
2549 case 'ScreenDef'
2550 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'ScreenDef')
2551 argout1 = [];
2552 else
2553 argout1 = GlobalData.Program.ScreenDef;
2554 end
2555 case 'DecorationSize'
2556 if isempty(GlobalData) || isempty(GlobalData.Program) || ~isfield(GlobalData.Program, 'DecorationSize')
2557 argout1 = [];
2558 else
2559 argout1 = GlobalData.Program.DecorationSize;
2560 end
2561 case 'Layout'
2562 % Default or current layout structure
2563 if ~isfield(GlobalData, 'Preferences') || ~isfield(GlobalData.Preferences, 'Layout') || ~((nargin == 1) || isfield(GlobalData.Preferences.Layout, varargin{2})) || ~isfield(GlobalData.Preferences.Layout, 'MainWindowPos')
2564 GlobalData.Preferences.Layout = db_template('Layout');
2565 end
2566 % Structure or property call
2567 if (nargin == 2) && ischar(varargin{2}) && isfield(GlobalData.Preferences.Layout, varargin{2})
2568 argout1 = GlobalData.Preferences.Layout.(varargin{2});
2569 elseif (nargin == 1)
2570 argout1 = GlobalData.Preferences.Layout;
2571 else
2572 error('Invalid call to bst_get.');
2573 end
2574
2575 case 'ByteOrder'
2576 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ByteOrder')
2577 argout1 = GlobalData.Preferences.ByteOrder;
2578 else
2579 argout1 = 'l';
2580 end
2581
2582 case 'UniformizeTimeSeriesScales'
2583 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'UniformizeTimeSeriesScales')
2584 argout1 = GlobalData.Preferences.UniformizeTimeSeriesScales;
2585 else
2586 argout1 = 1;
2587 end
2588
2589 case 'FlipYAxis'
2590 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'FlipYAxis')
2591 argout1 = GlobalData.Preferences.FlipYAxis;
2592 else
2593 argout1 = 0;
2594 end
2595
2596 case 'AutoScaleY'
2597 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'AutoScaleY')
2598 argout1 = GlobalData.Preferences.AutoScaleY;
2599 else
2600 argout1 = 1;
2601 end
2602
2603 case 'ShowXGrid'
2604 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowXGrid')
2605 argout1 = GlobalData.Preferences.ShowXGrid;
2606 else
2607 argout1 = 0;
2608 end
2609
2610 case 'ShowYGrid'
2611 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowYGrid')
2612 argout1 = GlobalData.Preferences.ShowYGrid;
2613 else
2614 argout1 = 0;
2615 end
2616
2617 case 'ShowZeroLines'
2618 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowZeroLines')
2619 argout1 = GlobalData.Preferences.ShowZeroLines;
2620 else
2621 argout1 = 1;
2622 end
2623
2624 case 'Resolution'
2625 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'Resolution')
2626 argout1 = GlobalData.Preferences.Resolution;
2627 else
2628 argout1 = [0 0];
2629 end
2630
2631 case 'FixedScaleY'
2632 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'FixedScaleY') && isfield(GlobalData.Preferences.FixedScaleY, varargin{2}) && ~isempty(GlobalData.Preferences.FixedScaleY.(varargin{2}))
2633 argout1 = GlobalData.Preferences.FixedScaleY.(varargin{2});
2634 else
2635 argout1 = [];
2636 end
2637
2638 case 'XScale'
2639 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'XScale')
2640 argout1 = GlobalData.Preferences.XScale;
2641 else
2642 argout1 = 'linear';
2643 end
2644
2645 case 'YScale'
2646 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'YScale')
2647 argout1 = GlobalData.Preferences.YScale;
2648 else
2649 argout1 = 'linear';
2650 end
2651
2652 case 'ShowEventsMode'
2653 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ShowEventsMode')
2654 argout1 = GlobalData.Preferences.ShowEventsMode;
2655 else
2656 argout1 = 'dot';
2657 end
2658
2659 case 'AutoUpdates'
2660 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'AutoUpdates')
2661 argout1 = GlobalData.Preferences.AutoUpdates;
2662 else
2663 argout1 = 1;
2664 end
2665
2666 case 'ForceMatCompression'
2667 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ForceMatCompression')
2668 argout1 = GlobalData.Preferences.ForceMatCompression;
2669 else
2670 argout1 = 0;
2671 end
2672
2673 case 'IgnoreMemoryWarnings'
2674 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'IgnoreMemoryWarnings')
2675 argout1 = GlobalData.Preferences.IgnoreMemoryWarnings;
2676 else
2677 argout1 = 0;
2678 end
2679
2680 case 'SystemCopy'
2681 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'SystemCopy')
2682 argout1 = GlobalData.Preferences.SystemCopy;
2683 else
2684 argout1 = 0;
2685 end
2686
2687 case 'ExpertMode'
2688 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ExpertMode')
2689 argout1 = GlobalData.Preferences.ExpertMode;
2690 else
2691 argout1 = 0;
2692 end
2693
2694 case 'DisplayGFP'
2695 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DisplayGFP')
2696 argout1 = GlobalData.Preferences.DisplayGFP;
2697 else
2698 argout1 = 1;
2699 end
2700
2701 case 'DownsampleTimeSeries'
2702 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DownsampleTimeSeries')
2703 if (GlobalData.Preferences.DownsampleTimeSeries == 1)
2704 GlobalData.Preferences.DownsampleTimeSeries = 5;
2705 end
2706 argout1 = GlobalData.Preferences.DownsampleTimeSeries;
2707 else
2708 argout1 = 5;
2709 end
2710
2711 case 'GraphicsSmoothing'
2712 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'GraphicsSmoothing')
2713 argout1 = GlobalData.Preferences.GraphicsSmoothing;
2714 else
2715 argout1 = 5;
2716 end
2717
2718 case 'DisableOpenGL'
2719 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'DisableOpenGL')
2720 argout1 = GlobalData.Preferences.DisableOpenGL;
2721 else
2722 argout1 = 0;
2723 end
2724
2725 case 'InterfaceScaling'
2726 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'InterfaceScaling')
2727 argout1 = GlobalData.Preferences.InterfaceScaling;
2728 else
2729 % Get screen resolution
2730 if isfield(GlobalData, 'Program') && isfield(GlobalData.Program, 'ScreenDef') && isfield(GlobalData.Program.ScreenDef, 'javaPos') && ~isempty(GlobalData.Program.ScreenDef(1).javaPos)
2731 AvailableRes = [100 125 150 200 250 300 400];
2732 iRes = bst_closest(GlobalData.Program.ScreenDef(1).javaPos.width * 100 / 1920, AvailableRes);
2733 argout1 = AvailableRes(iRes);
2734 else
2735 argout1 = 100;
2736 end
2737 end
2738
2739 case 'TSDisplayMode'
2740 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'TSDisplayMode')
2741 argout1 = GlobalData.Preferences.TSDisplayMode;
2742 else
2743 argout1 = 'butterfly';
2744 end
2745
2746 case 'PluginCustomPath'
2747 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'PluginCustomPath') && ~isempty(GlobalData.Preferences.PluginCustomPath)
2748 argout1 = GlobalData.Preferences.PluginCustomPath;
2749 else
2750 argout1 = [];
2751 end
2752
2753 case 'BrainSuiteDir'
2754 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BrainSuiteDir') && ~isempty(GlobalData.Preferences.BrainSuiteDir)
2755 if isdir(GlobalData.Preferences.BrainSuiteDir) && file_exist(bst_fullfile(GlobalData.Preferences.BrainSuiteDir, 'bdp'))
2756 argout1 = GlobalData.Preferences.BrainSuiteDir;
2757 else
2758 argout1 = [];
2759 end
2760 else
2761 argout1 = [];
2762 end
2763
2764 case 'SpmTpmAtlas'
2765 % Get template file
2766 tpmUser = bst_fullfile(bst_get('BrainstormUserDir'), 'defaults', 'spm', 'TPM.nii');
2767 if file_exist(tpmUser)
2768 argout1 = tpmUser;
2769 disp(['SPM12 template found: ' tpmUser]);
2770 return;
2771 end
2772 % If it does not exist: check in brainstorm3 folder
2773 tpmDistrib = bst_fullfile(bst_get('BrainstormHomeDir'), 'defaults', 'spm', 'TPM.nii');
2774 if file_exist(tpmDistrib)
2775 argout1 = tpmDistrib;
2776 disp(['SPM12 template found: ' tpmDistrib]);
2777 return;
2778 end
2779 % If it does not exist: check in spm12 folder
2780 PlugSpm = bst_plugin('GetInstalled', 'spm12');
2781 if ~isempty(PlugSpm)
2782 tpmSpm = bst_fullfile(PlugSpm.Path, PlugSpm.SubFolder, 'tpm', 'TPM.nii');
2783 if file_exist(tpmSpm)
2784 argout1 = tpmSpm;
2785 disp(['SPM12 template found: ' tpmSpm]);
2786 return;
2787 end
2788 else
2789 tpmSpm = '';
2790 end
2791 % Not found...
2792 disp('SPM12 template not found in any of the following folders:');
2793 disp([' - ' tpmUser]);
2794 disp([' - ' tpmDistrib]);
2795 if ~isempty(tpmSpm)
2796 disp([' - ' tpmSpm]);
2797 end
2798 % Return the preferred location: .brainstorm/defaults/spm/TPM.nii
2799 argout1 = tpmUser;
2800
2801 case 'PythonExe'
2802 % Get saved value
2803 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'PythonExe') && ~isempty(GlobalData.Preferences.PythonExe)
2804 if file_exist(GlobalData.Preferences.PythonExe)
2805 argout1 = GlobalData.Preferences.PythonExe;
2806 else
2807 disp(['BST> Error: Python executable not found: ' GlobalData.Preferences.PythonExe]);
2808 argout1 = [];
2809 end
2810 else
2811 argout1 = [];
2812 end
2813 % If not defined in Brainstorm, but set in Matlab
2814 if isempty(argout1)
2815 [pyVer, PythonExe] = bst_python_ver();
2816 if ~isempty(PythonExe) && file_exist(PythonExe)
2817 disp(['BST> Found Python executable: ' PythonExe]);
2818 argout1 = PythonExe;
2819 bst_set('PythonExe', PythonExe);
2820 end
2821 end
2822
2823 case 'ElectrodeConfig'
2824 % Get modality
2825 Modality = varargin{2};
2826 if isempty(Modality) || ~ismember(Modality, {'EEG','ECOG','SEEG','ECOG+SEEG'})
2827 disp(['GET> Invalid modality: ' Modality]);
2828 Modality = 'EEG';
2829 end
2830 % Value was saved previously
2831 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'ElectrodeConfig') && isfield(GlobalData.Preferences.ElectrodeConfig, Modality) && isfield(GlobalData.Preferences.ElectrodeConfig.(Modality), 'ContactDiameter')
2832 argout1 = GlobalData.Preferences.ElectrodeConfig.(Modality);
2833 % Get default value
2834 else
2835 switch (Modality)
2836 case 'EEG'
2837 ElectrodeConfig.Type = 'eeg';
2838 ElectrodeConfig.ContactDiameter = 0.010;
2839 ElectrodeConfig.ContactLength = 0.002;
2840 ElectrodeConfig.ElecDiameter = [];
2841 ElectrodeConfig.ElecLength = [];
2842 case 'ECOG'
2843 ElectrodeConfig.Type = 'ecog';
2844 ElectrodeConfig.ContactDiameter = 0.004;
2845 ElectrodeConfig.ContactLength = 0.001;
2846 ElectrodeConfig.ElecDiameter = 0.0005;
2847 ElectrodeConfig.ElecLength = [];
2848 case {'SEEG','ECOG+SEEG'}
2849 ElectrodeConfig.Type = 'seeg';
2850 ElectrodeConfig.ContactDiameter = 0.0008;
2851 ElectrodeConfig.ContactLength = 0.002;
2852 ElectrodeConfig.ElecDiameter = 0.0007;
2853 ElectrodeConfig.ElecLength = 0.070;
2854 end
2855 argout1 = ElectrodeConfig;
2856 end
2857
2858 case 'UseSigProcToolbox'
2859 % In a parfor loop: GlobalData is empty => Check only if the toolbox is installed (ignore user preferences)
2860 if isempty(GlobalData) || ~isfield(GlobalData, 'Program') || ~isfield(GlobalData.Program, 'HasSigProcToolbox')
2861 argout1 = exist('fir2', 'file');
2862 else
2863 % Save the result of the check for the SigProc tb
2864 if isempty(GlobalData.Program.HasSigProcToolbox)
2865 % Check if Signal Processing Toolbox is installed
2866 GlobalData.Program.HasSigProcToolbox = (exist('fir2', 'file') == 2);
2867 end
2868 % Return user preferences
2869 if ~GlobalData.Program.HasSigProcToolbox
2870 argout1 = 0;
2871 elseif isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'UseSigProcToolbox')
2872 argout1 = GlobalData.Preferences.UseSigProcToolbox;
2873 else
2874 argout1 = 1;
2875 end
2876 end
2877
2878 case 'CustomColormaps'
2879 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'CustomColormaps') && ~isempty(GlobalData.Preferences.CustomColormaps)
2880 argout1 = GlobalData.Preferences.CustomColormaps;
2881 else
2882 argout1 = repmat(struct('Name', '', 'CMap', []), 0);
2883 end
2884
2885 case 'BFSProperties'
2886 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'BFSProperties') && ~isempty(GlobalData.Preferences.BFSProperties)
2887 argout1 = GlobalData.Preferences.BFSProperties;
2888 else
2889 argout1 = [.33 .0042 .33 .88 .93];
2890 end
2891
2892 case 'LastUsedDirs'
2893 defPref = struct(...
2894 'ImportData', '', ...
2895 'ImportChannel', '', ...
2896 'ImportAnat', '', ...
2897 'ImportMontage', '', ...
2898 'ExportChannel', '', ...
2899 'ExportData', '', ...
2900 'ExportAnat', '', ...
2901 'ExportProtocol', '', ...
2902 'ExportImage', '', ...
2903 'ExportScript', '', ...
2904 'ExportMontage', '');
2905 argout1 = FillMissingFields(contextName, defPref);
2906 % Check that all folders are valid
2907 fields = fieldnames(argout1);
2908 for i = 1:length(fields)
2909 if ~ischar(argout1.(fields{i})) || ~file_exist(argout1.(fields{i}))
2910 argout1.(fields{i}) = '';
2911 end
2912 end
2913
2914 case 'DefaultFormats'
2915 defPref = struct(...
2916 'AnatIn', 'FreeSurfer', ...
2917 'ChannelIn', '', ...
2918 'ChannelOut', '', ...
2919 'DataIn', 'CTF', ...
2920 'DataOut', '', ...
2921 'DipolesIn', '', ...
2922 'DipolesOut', '', ...
2923 'ImageOut', '', ...
2924 'EventsIn', '', ...
2925 'EventsOut', '', ...
2926 'MriIn', '', ...
2927 'MriOut', 'Nifti1', ...
2928 'NoiseCovIn', '', ...
2929 'NoiseCovOut', '', ...
2930 'ResultsIn', '', ...
2931 'ResultsOut', '', ...
2932 'SpmOut', '', ...
2933 'SspIn', '', ...
2934 'SspOut', '', ...
2935 'SurfaceIn', '', ...
2936 'SurfaceOut', '', ...
2937 'LabelIn', '', ...
2938 'LabelOut', '', ...
2939 'TimefreqIn', '', ...
2940 'TimefreqOut', '', ...
2941 'MatrixIn', '', ...
2942 'MatrixOut', '', ...
2943 'MontageIn', '', ...
2944 'MontageOut', '', ...
2945 'FibersIn', '');
2946 argout1 = FillMissingFields(contextName, defPref);
2947
2948 case 'OsType'
2949 switch (mexext)
2950 case 'mexglx', argout1 = 'linux32';
2951 case 'mexa64', argout1 = 'linux64';
2952 case 'mexmaci', argout1 = 'mac32';
2953 case 'mexmaci64', argout1 = 'mac64';
2954 case 'mexmaca64', argout1 = 'mac64arm';
2955 case 'mexs64', argout1 = 'sol64';
2956 case 'mexw32', argout1 = 'win32';
2957 case 'mexw64', argout1 = 'win64';
2958 otherwise, error('Unsupported extension.');
2959 end
2960 % CALL: bst_get('OsType', isMatlab=0)
2961 if (nargin >= 2) && isequal(varargin{2}, 0)
2962 if strcmpi(argout1, 'win32') && (~isempty(strfind(java.lang.System.getProperty('java.home'), '(x86)')) || ~isempty(strfind(java.lang.System.getenv('ProgramFiles(x86)'), '(x86)')))
2963 argout1 = 'win64';
2964 end
2965 end
2966
2967 case 'ImportDataOptions'
2968 defPref = db_template('ImportOptions');
2969 argout1 = FillMissingFields(contextName, defPref);
2970
2971 case 'RawViewerOptions'
2972 defPref = struct(...
2973 'PageDuration', 3, ...
2974 'RemoveBaseline', 'all', ...
2975 'UseCtfComp', 1, ...
2976 'Shortcuts', []);
2977 defPref.Shortcuts = {...
2978 '1', 'event1', 'simple', []; ... % Key, event name, event type (simple,extended,page), epoch time
2979 '2', 'event2', 'simple', []; ...
2980 '3', 'event3', 'simple', []; ...
2981 '4', 'event4', 'simple', []; ...
2982 '5', 'event5', 'simple', []; ...
2983 '6', 'event6', 'simple', []; ...
2984 '7', 'event7', 'simple', []; ...
2985 '8', 'event8', 'simple', []; ...
2986 '9', 'event9', 'simple', []};
2987 argout1 = FillMissingFields(contextName, defPref);
2988 % If invalid PageDuration: reset to default
2989 if (argout1.PageDuration <= 0.1)
2990 argout1.PageDuration = defPref.PageDuration;
2991 end
2992 % If old shortcuts: reset to defaults
2993 if any(size(argout1.Shortcuts) ~= size(defPref.Shortcuts))
2994 disp('BST> Warning: Reset keyboard shortcuts to include new options.');
2995 argout1.Shortcuts = defPref.Shortcuts;
2996 bst_set('RawViewerOptions', argout1);
2997 end
2998
2999 case 'MontageOptions'
3000 defPref = struct('Shortcuts', []);
3001 defPref.Shortcuts = {
3002 %'a', []; ... Note: A is reserved for All channels
3003 'b', []; ...
3004 'c', []; ...
3005 'd', []; ...
3006 'e', []; ...
3007 'f', []; ...
3008 'g', []; ...
3009 'h', []; ...
3010 'i', []; ...
3011 'j', []; ...
3012 'k', []; ...
3013 'l', []; ...
3014 'm', []; ...
3015 'n', []; ...
3016 'o', []; ...
3017 'p', []; ...
3018 'q', []; ...
3019 'r', []; ...
3020 's', []; ...
3021 't', []; ...
3022 'u', []; ...
3023 'v', []; ...
3024 'w', []; ...
3025 'x', []; ...
3026 'y', []; ...
3027 'z', []; ...
3028 };
3029 argout1 = FillMissingFields(contextName, defPref);
3030
3031 case 'TopoLayoutOptions'
3032 defPref = struct(...
3033 'TimeWindow', [], ...
3034 'WhiteBackground', 0, ...
3035 'ShowRefLines', 1, ...
3036 'ShowLegend', 1, ...
3037 'FlipYAxis', 0, ...
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) && ((size(argout1.FreqBands,2) ~= 3) || ~all(cellfun(@ischar, argout1.FreqBands(:))) || any(cellfun(@(c)isempty(strtrim(c)), argout1.FreqBands(:))))
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) && (size(argout1.FreqBands,2) == 3) && ~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 'ConnectGraphOptions'
3292 % Get interface scaling factor
3293 InterfaceScaling = bst_get('InterfaceScaling');
3294 % Get default values
3295 defPref = struct(...
3296 'LobeFullLabel', 1, ...
3297 'TextDisplayMode', [1 2], ...
3298 'LabelSize', 7 .* InterfaceScaling ./ 100, ...
3299 'NodeSize', 5 .* InterfaceScaling ./ 100, ...
3300 'LinkSize', 1.5 .* InterfaceScaling ./ 100, ...
3301 'BgColor', [0 0 0], ...
3302 'HierarchyNodeIsVisible', 1);
3303 % If we have an additional argument, get the default values
3304 if nargin > 1
3305 argout1 = defPref;
3306 % Otherwise, get the saved values
3307 else
3308 savedValues = FillMissingFields(contextName, defPref);
3309
3310 % if any of the fields are [], replace by default value
3311 % do it here to avoid touching the common FillMissingFields
3312 % function, as other tools may actually want to set [] as desired property
3313 fields = fieldnames(savedValues);
3314 for i=1:numel(fields)
3315 if(isempty(savedValues.(fields{i})))
3316 savedValues.(fields{i}) = defPref.(fields{i});
3317 end
3318 end
3319 argout1 = savedValues;
3320 end
3321
3322 case 'NodelistOptions'
3323 defPref = struct(...
3324 'String', '', ... % What to search for
3325 'Target', 'Comment', ... % What field to search for: {'FileName', 'Comment'}
3326 'Action', 'Select'); % What to do with the filtered files: {'Select', 'Exclude'}
3327 argout1 = FillMissingFields(contextName, defPref);
3328
3329 case 'ReadOnly'
3330 if isfield(GlobalData.DataBase, 'isReadOnly')
3331 argout1 = GlobalData.DataBase.isReadOnly;
3332 else
3333 argout1 = 0;
3334 end
3335
3336 case 'LastPsdDisplayFunction'
3337 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'LastPsdDisplayFunction')
3338 argout1 = GlobalData.Preferences.LastPsdDisplayFunction;
3339 else
3340 argout1 = [];
3341 end
3342
3343 case 'PlotlyCredentials'
3344 % Get saved username and API key
3345 try
3346 creds = loadplotlycredentials();
3347 argout1 = creds.username;
3348 argout2 = creds.api_key;
3349 catch
3350 argout1 = '';
3351 argout2 = '';
3352 end
3353 % Get saved domain
3354 try
3355 config = loadplotlyconfig();
3356 argout3 = config.plotly_domain;
3357 catch
3358 argout3 = '';
3359 end
3360
3361 case 'KlustersExecutable'
3362 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, 'KlustersExecutable')
3363 argout1 = GlobalData.Preferences.KlustersExecutable;
3364 else
3365 argout1 = [];
3366 end
3367
3368
3369 %% ===== FILE FILTERS =====
3370 case 'FileFilters'
3371 switch lower(varargin{2})
3372 case 'mri'
3373 argout1 = {...
3374 {'.img'}, 'MRI: Analyze (*.img/*.hdr)', 'Analyze'; ...
3375 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3376 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3377 {'.mri'}, 'MRI: CTF (*.mri)', 'CTF'; ...
3378 {'.mat'}, 'MRI: FieldTrip (*.mat)', 'FT-MRI'; ...
3379 {'.mgh','.mgz'}, 'MRI: MGH (*.mgh,*.mgz)', 'MGH'; ...
3380 {'.mnc', '.mni'}, 'MRI: MNI (*.mnc,*.mni)', 'MINC'; ...
3381 {'.nii','.gz'}, 'MRI: NIfTI-1 (*.nii;*.nii.gz)', 'Nifti1'; ...
3382 {'_subjectimage'}, 'MRI: Brainstorm (*subjectimage*.mat)', 'BST'; ...
3383 {'*'}, 'MRI: DICOM (SPM converter)', 'DICOM-SPM'; ...
3384 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'All MRI files (subject space)', 'ALL'; ...
3385 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'All MRI files (MNI space)', 'ALL-MNI'; ...
3386 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume atlas (subject space)', 'ALL-ATLAS'; ...
3387 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume atlas (MNI space)', 'ALL-MNI-ATLAS'; ...
3388 };
3389 case 'mriout'
3390 argout1 = {...
3391 {'.img'}, 'MRI: Analyze (*.img/*.hdr)', 'Analyze'; ...
3392 {'.ima'}, 'MRI: BrainVISA GIS (*.ima/*.dim)', 'GIS'; ...
3393 {'.mri'}, 'MRI: CTF (*.mri)', 'CTF'; ...
3394 {'.mat'}, 'MRI: FieldTrip (*.mat)', 'FT-MRI'; ...
3395 {'.nii'}, 'MRI: NIfTI-1 (*.nii)', 'Nifti1'...
3396 };
3397 case 'anatin'
3398 argout1 = {...
3399 {'.folder'}, 'FreeSurfer', 'FreeSurfer-fast'; ...
3400 {'.folder'}, 'FreeSurfer + Volume atlases', 'FreeSurfer'; ...
3401 {'.folder'}, 'FreeSurfer + Volume atlases + Thickness', 'FreeSurfer+Thick'; ...
3402 {'.folder'}, 'BrainSuite', 'BrainSuite-fast'; ...
3403 {'.folder'}, 'BrainSuite + Volume atlases', 'BrainSuite'; ...
3404 {'.folder'}, 'BrainVISA', 'BrainVISA'; ...
3405 {'.folder'}, 'CAT12', 'CAT12'; ...
3406 {'.folder'}, 'CAT12 + Thickness', 'CAT12+Thick'; ...
3407 {'.folder'}, 'CIVET', 'CIVET'; ...
3408 {'.folder'}, 'CIVET + Thickness', 'CIVET+Thick'; ...
3409 {'.folder'}, 'HCP MEG/anatomy (pipeline v3)', 'HCPv3'; ...
3410 {'.folder'}, 'SimNIBS', 'SimNIBS'; ...
3411 };
3412 case 'source4d'
3413 argout1 = {...
3414 {'.folder'}, 'NIfTI-1 (*.nii)', 'Nifti1';...
3415 {'.folder'}, 'Analyze (*.img/*.hdr)', 'Analyze'; ...
3416 {'.folder'}, 'Matlab 4D matrix (*voltime*.mat)', 'BST'; ...
3417 };
3418
3419 case 'surface'
3420 argout1 = {...
3421 {'.mesh'}, 'BrainVISA (*.mesh)', 'MESH'; ...
3422 {'_tess', '_head', '_scalp', '_brain', '_cortex', '_innerskull', '_outerskull'}, 'Brainstorm (*.mat)', 'BST'; ...
3423 {'.dfs'}, 'BrainSuite (*.dfs)', 'DFS'; ...
3424 {'.dsgl'}, 'BrainSuite old (*.dsgl)', 'DSGL'; ...
3425 {'.bd0','.bd1','.bd2','.bd3','.bd4','.bd5','.bd6','.bd7','.bd8','.bd9', ...
3426 '.s00','.s01','.s02','.s03','.s04','.s05','.s06','.s07','.s08','.s09'}, ...
3427 'Curry BEM (*.db*;*.s0*)', 'CURRY-BEM';
3428 {'.vtk'}, 'FSL: VTK (*.vtk)', 'VTK'; ...
3429 {'*'}, 'FreeSurfer (*.*)', 'FS';
3430 {'.off'}, 'Geomview OFF (*.off)', 'OFF'; ...
3431 {'.gii'}, 'GIfTI / MRI coordinates (*.gii)', 'GII'; ...
3432 {'.gii'}, 'GIfTI / MNI coordinates (*.gii)', 'GII-MNI'; ...
3433 {'.gii'}, 'GIfTI / World coordinates (*.gii)', 'GII-WORLD'; ...
3434 {'.fif'}, 'MNE (*.fif)', 'FIF'; ...
3435 {'.obj'}, 'MNI OBJ (*.obj)', 'MNIOBJ'; ...
3436 {'.msh'}, 'SimNIBS Gmsh4 (*.msh)', 'SIMNIBS'; ...
3437 {'.tri'}, 'TRI (*.tri)', 'TRI'; ...
3438 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (subject space)', 'MRI-MASK'; ...
3439 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (MNI space)', 'MRI-MASK-MNI'; ...
3440 {'.nwbaux'}, 'Neurodata Without Borders (*.nwbaux)', 'NWB'; ...
3441 {'*'}, 'All surface files (*.*)', 'ALL'; ...
3442 };
3443
3444 case 'surfaceout'
3445 argout1 = {...
3446 {'.mesh'}, 'BrainVISA (*.mesh)', 'MESH'; ...
3447 {'.dfs'}, 'BrainSuite (*.dfs)', 'DFS'; ...
3448 {'.fs'}, 'FreeSurfer (*.fs)', 'FS'
3449 {'.off'}, 'Geomview OFF (*.off)', 'OFF'; ...
3450 {'.gii'}, 'GIfTI (*.gii)', 'GII'; ...
3451 {'.tri'}, 'TRI (*.tri)', 'TRI'; ...
3452 };
3453
3454 case 'data'
3455 argout1 = {...
3456 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3457 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF'; ...
3458 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3459 {'.mat'}, 'MEG/EEG: FieldTrip (*.mat)', 'FT-TIMELOCK'; ...
3460 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3461 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3462 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3463 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3464 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3465 {'.meghdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.meghdf5)', 'MEGSCAN-HDF5'; ...
3466 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3467 {'.adicht'}, 'EEG: ADInstruments LabChart (*.adicht)', 'EEG-ADICHT'; ...
3468 {'.msr'}, 'EEG: ANT ASA (*.msr)', 'EEG-ANT-MSR'; ...
3469 {'.cnt','.avr'}, 'EEG: ANT EEProbe (*.cnt;*.avr)', 'EEG-ANT-CNT'; ...
3470 {'*'}, 'EEG: ASCII text (*.*)', 'EEG-ASCII'; ...
3471 {'.raw'}, 'EEG: Axion AxIS (*.raw)', 'EEG-AXION'; ...
3472 {'.bdf'}, 'EEG: BDF (*.bdf)', 'EEG-BDF'; ...
3473 {'.avr','.mux','.mul'}, 'EEG: BESA exports (*.avr;*.mul;*.mux)', 'EEG-BESA'; ...
3474 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Blackrock NeuroPort (*.nsX/*.nev)', 'EEG-BLACKROCK';
3475 {'.eeg','.dat'}, 'EEG: BrainVision BrainAmp (*.eeg;*.dat)', 'EEG-BRAINAMP'; ...
3476 {'.txt'}, 'EEG: BrainVision Analyzer (*.txt)', 'EEG-BRAINVISION'; ...
3477 {'.sef','.ep','.eph'}, 'EEG: Cartool (*.sef;*.ep;*.eph)', 'EEG-CARTOOL'; ...
3478 {'.dat','.cdt'}, 'EEG: Curry (*.dat;*.cdt)', 'EEG-CURRY'; ...
3479 {'.smr','.son'}, 'EEG: CED Spike2 old 32bit (*.smr;*.son)', 'EEG-SMR'; ...
3480 {'.smr','.smrx'}, 'EEG: CED Spike2 new 64bit (*.smr;*.smrx)', 'EEG-SMRX'; ...
3481 {'.rda'}, 'EEG: Compumedics ProFusion Sleep (*.rda)', 'EEG-COMPUMEDICS-PFS'; ...
3482 {'.bin'}, 'EEG: Deltamed Coherence-Neurofile (*.bin)', 'EEG-DELTAMED'; ...
3483 {'.edf','.rec'}, 'EEG: EDF / EDF+ (*.rec;*.edf)', 'EEG-EDF'; ...
3484 {'.set'}, 'EEG: EEGLAB (*.set)', 'EEG-EEGLAB'; ...
3485 {'.raw'}, 'EEG: EGI Netstation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3486 {'.mff','.bin'}, 'EEG: EGI-Philips (*.mff)', 'EEG-EGI-MFF'; ...
3487 {'.edf'}, 'EEG: EmotivPRO (*.edf)', 'EEG-EMOTIV'; ...
3488 {'.erp','.hdr'}, 'EEG: ERPCenter (*.hdr;*.erp)', 'EEG-ERPCENTER'; ...
3489 {'.erp'}, 'EEG: ERPLab (*.erp)', 'EEG-ERPLAB'; ...
3490 {'.mat','.hdf5'}, 'EEG: g.tec Matlab (*.mat,*.hdf5)', 'EEG-GTEC'; ...
3491 {'.rhd','.rhs'}, 'EEG: Intan (*.rhd,*.rhs)', 'EEG-INTAN'; ...
3492 {'.mb2'}, 'EEG: MANSCAN (*.mb2)', 'EEG-MANSCAN'; ...
3493 {'.trc'}, 'EEG: Micromed (*.trc)', 'EEG-MICROMED'; ...
3494 {'.mat'}, 'EEG: Matlab matrix (*.mat)', 'EEG-MAT'; ...
3495 {'.csv'}, 'EEG: Muse (*.csv)', 'EEG-MUSE-CSV'; ...
3496 {'.ncs'}, 'EEG: Neuralynx (*.ncs)', 'EEG-NEURALYNX'; ...
3497 {'.nwb'}, 'EEG: Neurodata Without Borders (*.nwb)','NWB'; ...
3498 {'.nedf','.easy'}, 'EEG: Neuroelectrics (*.nedf;*.easy)', 'EEG-NEUROELECTRICS'; ...
3499 {'.bin'}, 'EEG: NeurOne session folder', 'EEG-NEURONE'; ...
3500 {'.cnt','.avg','.eeg','.dat'}, 'EEG: Neuroscan (*.cnt;*.eeg;*.avg;*.dat)', 'EEG-NEUROSCAN'; ...
3501 {'.eeg','.dat'}, 'EEG: NeuroScope (*.eeg;*.dat)', 'EEG-NEUROSCOPE'; ...
3502 {'.e'}, 'EEG: Nicolet (*.e)', 'EEG-NICOLET'; ...
3503 {'.eeg'}, 'EEG: Nihon Kohden (*.eeg)', 'EEG-NK'; ...
3504 {'.dat'}, 'EEG: Open Ephys flat binary (*.dat)', 'EEG-OEBIN'; ...
3505 {'.plx','.pl2'}, 'EEG: Plexon (*.plx;*.pl2)', 'EEG-PLEXON'; ...
3506 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Ripple Trellis (*.nsX/*.nev)', 'EEG-RIPPLE'; ...
3507 {'.h5'}, 'EEG: The Virtual Brain (*_TimeSeriesEEG.h5)', 'EEG-TVB'; ...
3508 {'.csv'}, 'EEG: Wearable Sensing (*.csv)', 'EEG-WS-CSV'; ...
3509 {'.nirs'}, 'NIRS: Brainsight (*.nirs)', 'NIRS-BRS'; ...
3510 {'.bnirs','.jnirs','.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3511 {'.edf'}, 'Eye tracker: EyeLink (*.edf)', 'EYELINK'; ...
3512 {'.tsv'}, 'Eye tracker: Tobii glasses (*.tsv)', 'EYE-TOBII-TSV'; ...
3513 };
3514 case 'raw'
3515 argout1 = {...
3516 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3517 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF'; ...
3518 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3519 {'.mat'}, 'MEG/EEG: FieldTrip (*.mat)', 'FT-TIMELOCK'; ...
3520 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3521 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3522 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3523 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3524 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3525 {'.meghdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.meghdf5)', 'MEGSCAN-HDF5'; ...
3526 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3527 {'.adicht'}, 'EEG: ADInstruments LabChart (*.adicht)', 'EEG-ADICHT'; ...
3528 {'.msr'}, 'EEG: ANT ASA (*.msr)', 'EEG-ANT-MSR'; ...
3529 {'.cnt','.avr'}, 'EEG: ANT EEProbe (*.cnt;*.avr)', 'EEG-ANT-CNT'; ...
3530 {'*'}, 'EEG: ASCII text (*.*)', 'EEG-ASCII'; ...
3531 {'.raw'}, 'EEG: Axion AxIS (*.raw)', 'EEG-AXION'; ...
3532 {'.bdf'}, 'EEG: BDF (*.bdf)', 'EEG-BDF'; ...
3533 {'.avr','.mux','.mul'}, 'EEG: BESA exports (*.avr;*.mul;*.mux)', 'EEG-BESA'; ...
3534 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Blackrock NeuroPort (*.nsX/*.nev)', 'EEG-BLACKROCK';
3535 {'.eeg','.dat'}, 'EEG: BrainVision BrainAmp (*.eeg;*.dat)', 'EEG-BRAINAMP'; ...
3536 {'.txt'}, 'EEG: BrainVision Analyzer (*.txt)', 'EEG-BRAINVISION'; ...
3537 {'.sef','.ep','.eph'}, 'EEG: Cartool (*.sef;*.ep;*.eph)', 'EEG-CARTOOL'; ...
3538 {'.smr','.son'}, 'EEG: CED Spike2 old 32bit (*.smr;*.son)', 'EEG-SMR'; ...
3539 {'.smr','.smrx'}, 'EEG: CED Spike2 new 64bit (*.smr;*.smrx)', 'EEG-SMRX'; ...
3540 {'.rda'}, 'EEG: Compumedics ProFusion Sleep (*.rda)', 'EEG-COMPUMEDICS-PFS'; ...
3541 {'.dat','.cdt'}, 'EEG: Curry (*.dat;*.cdt)', 'EEG-CURRY'; ...
3542 {'.bin'}, 'EEG: Deltamed Coherence-Neurofile (*.bin)', 'EEG-DELTAMED'; ...
3543 {'.edf','.rec'}, 'EEG: EDF / EDF+ (*.rec;*.edf)', 'EEG-EDF'; ...
3544 {'.set'}, 'EEG: EEGLAB (*.set)', 'EEG-EEGLAB'; ...
3545 {'.raw'}, 'EEG: EGI Netstation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3546 {'.mff','.bin'}, 'EEG: EGI-Philips (*.mff)', 'EEG-EGI-MFF'; ...
3547 {'.edf'}, 'EEG: EmotivPRO (*.edf)', 'EEG-EMOTIV'; ...
3548 {'.mat','.hdf5'}, 'EEG: g.tec Matlab (*.mat,*.hdf5)', 'EEG-GTEC'; ...
3549 {'.rhd','.rhs'}, 'EEG: Intan (*.rhd,*.rhs)', 'EEG-INTAN'; ...
3550 {'.mb2'}, 'EEG: MANSCAN (*.mb2)', 'EEG-MANSCAN'; ...
3551 {'.mat'}, 'EEG: Matlab matrix (*.mat)', 'EEG-MAT'; ...
3552 {'.csv'}, 'EEG: Muse (*.csv)', 'EEG-MUSE-CSV'; ...
3553 {'.trc'}, 'EEG: Micromed (*.trc)', 'EEG-MICROMED'; ...
3554 {'.ncs'}, 'EEG: Neuralynx (*.ncs)', 'EEG-NEURALYNX'; ...
3555 {'.nwb'}, 'EEG: Neurodata Without Borders (*.nwb)','NWB'; ...
3556 {'.nedf','.easy'}, 'EEG: Neuroelectrics (*.nedf;*.easy)', 'EEG-NEUROELECTRICS'; ...
3557 {'.bin'}, 'EEG: NeurOne session folder', 'EEG-NEURONE'; ...
3558 {'.cnt','.avg','.eeg','.dat'}, 'EEG: Neuroscan (*.cnt;*.eeg;*.avg;*.dat)', 'EEG-NEUROSCAN'; ...
3559 {'.eeg','.dat'}, 'EEG: NeuroScope (*.eeg;*.dat)', 'EEG-NEUROSCOPE'; ...
3560 {'.e'}, 'EEG: Nicolet (*.e)', 'EEG-NICOLET'; ...
3561 {'.eeg'}, 'EEG: Nihon Kohden (*.eeg)', 'EEG-NK'; ...
3562 {'.dat'}, 'EEG: Open Ephys flat binary (*.dat)', 'EEG-OEBIN'; ...
3563 {'.plx','.pl2'}, 'EEG: Plexon (*.plx;.pl2)' 'EEG-PLEXON'; ...
3564 {'.ns1','.ns2','.ns3','.ns4','.ns5','.ns6'}, 'EEG: Ripple Trellis (*.nsX/*.nev)', 'EEG-RIPPLE'; ...
3565 {'.h5'}, 'EEG: The Virtual Brain (*_TimeSeriesEEG.h5)', 'EEG-TVB'; ...
3566 {'.tbk'}, 'EEG: Tucker Davis Technologies (*.tbk)', 'EEG-TDT'; ...
3567 {'.csv'}, 'EEG: Wearable Sensing (*.csv)', 'EEG-WS-CSV'; ...
3568 {'.trc','.eeg','.e','.bin','.rda','.edf','.bdf'}, 'SEEG: Deltamed/Micromed/NK/Nicolet/BrainVision/EDF', 'SEEG-ALL'; ...
3569 {'.trc','.eeg','.e','.bin','.rda','.edf','.bdf'}, 'ECOG: Deltamed/Micromed/NK/Nicolet/BrainVision/EDF', 'ECOG-ALL'; ...
3570 {'.nirs'}, 'NIRS: Brainsight (*.nirs)', 'NIRS-BRS'; ...
3571 {'.bnirs','.jnirs','.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3572 {'.edf'}, 'Eye tracker: EyeLink (*.edf)', 'EYELINK'; ...
3573 {'.tsv'}, 'Eye tracker: Tobii glasses (*.tsv)', 'EYE-TOBII-TSV'; ...
3574 };
3575
3576 case 'dataout'
3577 argout1 = {...
3578 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3579 {'.mat'}, 'MEG/EEG: FieldTrip timelock (*.mat)', 'FT-TIMELOCK'; ...
3580 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3581 {'.eeg'}, 'EEG: BrainVision BrainAmp (*.eeg)', 'EEG-BRAINAMP'; ...
3582 {'.eph'}, 'EEG: Cartool EPH (*.eph)', 'EEG-CARTOOL-EPH'; ...
3583 {'.raw'}, 'EEG: EGI NetStation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3584 {'.edf'}, 'EEG: European Data Format (*.edf)', 'EEG-EDF'; ...
3585 {'.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3586 {'.txt'}, 'ASCII: Space-separated, fixed column size (*.txt)', 'ASCII-SPC'; ...
3587 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3588 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3589 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3590 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3591 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3592 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3593 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3594 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3595 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3596 {'_timeseries'}, 'Brainstorm matrix (*timeseries*.mat)', 'BST'; ...
3597 };
3598 case 'rawout'
3599 argout1 = {...
3600 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3601 {'.mat'}, 'MEG/EEG: SPM (*.mat/.dat)', 'SPM-DAT'; ...
3602 {'.eeg'}, 'EEG: BrainVision BrainAmp (*.eeg)', 'EEG-BRAINAMP'; ...
3603 {'.raw'}, 'EEG: EGI NetStation RAW (*.raw)', 'EEG-EGI-RAW'; ...
3604 {'.edf'}, 'EEG: European Data Format (*.edf)', 'EEG-EDF'; ...
3605 {'.snirf'}, 'NIRS: SNIRF (*.snirf)', 'NIRS-SNIRF'; ...
3606 };
3607 case 'events'
3608 argout1 = {...
3609 {'.trg'}, 'ANT EEProbe (*.trg)', 'ANT'; ...
3610 {'.mrk'}, 'AnyWave (*.mrk)', 'ANYWAVE'; ...
3611 {'.evt'}, 'BESA (*.evt)', 'BESA'; ...
3612 {'.tsv'}, 'BIDS events: onset, duration, trial_type, channel (*.tsv)', 'BIDS'; ...
3613 {'.vmrk'}, 'BrainVision BrainAmp (*.vmrk)', 'BRAINAMP'; ...
3614 {'_events'}, 'Brainstorm (events*.mat)', 'BST'; ...
3615 {'.mrk'}, 'Cartool (*.mrk)', 'CARTOOL'; ...
3616 {'.mrk'}, 'CTF MarkerFile (*.mrk)', 'CTF'; ...
3617 {'.cef'}, 'Curry (*.cef)', 'CURRY'; ...
3618 {'.eve','.fif'}, 'Elekta-Neuromag MNE (*.eve;*.fif)', 'FIF'; ...
3619 {'.evl','.txt'}, 'Elekta-Neuromag Graph (*.evl;*.txt)', 'GRAPH'; ...
3620 {'.txt','.mat'}, 'FieldTrip trial definition (*.txt;*.mat)', 'TRL'; ...
3621 {'.trg'}, 'KRISS MEG (*.trg)', 'KDF'; ...
3622 {'.evt'}, 'Micromed (*.evt)', 'MICROMED'; ...
3623 {'.ev2'}, 'Neuroscan (*.ev2)', 'NEUROSCAN'; ...
3624 {'.txt'}, 'Nicolet export (*.txt)', 'NICOLET'; ...
3625 {'timestamps.npy'},'Open Ephys (timestamps.npy)', 'OEBIN'; ...
3626 {'.log'}, 'Presentation (*.log)', 'PRESENTATION'; ...
3627 {'.mrk','.sqd','.con','.raw','.ave'}, 'Ricoh (*.mrk;*.sqd;*.con;*.raw;*.ave)', 'RICOH'; ...
3628 {'.txt'}, 'XLTEK export (*.txt)', 'XLTEK'; ...
3629 {'.mrk','.sqd','.con','.raw','.ave'}, 'Yokogawa/KIT (*.mrk;*.sqd;*.con;*.raw;*.ave)', 'KIT'; ...
3630 {'.*'}, 'Array of times (*.mat;*.*)', 'ARRAY-TIMES'; ...
3631 {'.*'}, 'Array of samples (*.mat;*.*)', 'ARRAY-SAMPLES'; ...
3632 {'.txt','.csv'}, 'CSV text file: label, time, duration (*.txt;*.csv)', 'CSV-TIME'; ...
3633 {'.*'}, 'CTF Video Times (.txt)', 'CTFVIDEO'; ...
3634 };
3635 case 'eventsout'
3636 argout1 = {...
3637 {'.mrk'}, 'AnyWave (*.mrk)', 'ANYWAVE'; ...
3638 {'_events'}, 'Brainstorm (events*.mat)', 'BST'; ...
3639 {'.vmrk'}, 'BrainVision BrainAmp (*.vmrk)', 'BRAINAMP'; ...
3640 {'.mrk'}, 'CTF MarkerFile (*.mrk)', 'CTF'; ...
3641 {'.eve','.fif'}, 'Elekta-Neuromag/MNE (*.eve)', 'FIF'; ...
3642 {'.evl'}, 'Elekta-Neuromag Graph (Alternative Style) (*.evl)', 'GRAPH_ALT'; ...
3643 {'.txt'}, 'Array of times (*.txt)', 'ARRAY-TIMES'; ...
3644 {'.txt'}, 'Array of samples (*.txt)', 'ARRAY-SAMPLES'; ...
3645 {'.txt','.csv'}, 'CSV text file: label, time, duration (*.txt;*.csv)', 'CSV-TIME'; ...
3646 {'.txt'}, 'CTF Video Times (*.txt)', 'CTFVIDEO'; ...
3647 };
3648 case 'channel'
3649 argout1 = {...
3650 {'.*'}, 'MEG/EEG: 4D-Neuroimaging/BTi (*.*)', '4D'; ...
3651 {'.meg4','.res4'}, 'MEG/EEG: CTF (*.ds;*.meg4;*.res4)', 'CTF' ; ...
3652 {'.fif'}, 'MEG/EEG: Elekta-Neuromag (*.fif)', 'FIF'; ...
3653 {'.kdf'}, 'MEG/EEG: KRISS MEG (*.kdf)', 'KDF'; ...
3654 {'.raw'}, 'MEG/EEG: ITAB (*.raw)', 'ITAB'; ...
3655 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Ricoh (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'RICOH'; ...
3656 {'.mrk','.sqd','.con','.raw','.ave'}, 'MEG/EEG: Yokogawa/KIT (*.sqd;*.con;*.raw;*.ave;*.mrk)', 'KIT'; ...
3657 {'.meghdf5'}, 'MEG/EEG: York Instruments MEGSCAN (.meghdf5)', 'MEGSCAN-HDF5'; ...
3658 {'.bst'}, 'MEG/EEG: Brainstorm binary (*.bst)', 'BST-BIN'; ...
3659 {'_channel'}, 'MEG/EEG: Brainstorm (channel*.mat)', 'BST'; ...
3660 {'.elc'}, 'EEG: ANT ASA/Xensor (*.elc)', 'XENSOR'; ...
3661 {'.sfp','.elp','.ela','.eps'}, 'EEG: BESA (*.sfp;*.elp;*.eps/*.ela)', 'BESA'; ...
3662 {'.bvef','.bvct','.txt'}, 'EEG: BrainVision electrode file (*.bvef,*.bvct,*.txt)', 'BRAINVISION'; ...
3663 {'.tsv'}, 'EEG: BIDS electrodes.tsv, subject space mm (*.tsv)', 'BIDS-SCANRAS-MM'; ...
3664 {'.tsv'}, 'EEG: BIDS electrodes.tsv, MNI space mm (*.tsv)', 'BIDS-MNI-MM'; ...
3665 {'.els','.xyz'}, 'EEG: Cartool (*.els;*.xyz)', 'CARTOOL'; ...
3666 {'.eeg'}, 'EEG: MegDraw (*.eeg)', 'MEGDRAW'; ...
3667 {'.res','.rs3','.pom'}, 'EEG: Curry (*.res;*.rs3;*.pom)', 'CURRY'; ...
3668 {'.ced','.xyz','.set'}, 'EEG: EEGLAB (*.ced;*.xyz;*.set)', 'EEGLAB'; ...
3669 {'.elc'}, 'EEG: EETrak (*.elc)', 'EETRAK'; ...
3670 {'.sfp'}, 'EEG: EGI (*.sfp)', 'EGI'; ...
3671 {'coordinates.xml'}, 'EEG: EGI-Philips (coordinates.xml)', 'MFF'; ...
3672 {'.elp'}, 'EEG: EMSE (*.elp)', 'EMSE'; ...
3673 {'.pts','.csv'}, 'EEG: IntrAnat, subject space (*.pts;*.csv)', 'INTRANAT'; ...
3674 {'.pts','.csv'}, 'EEG: IntrAnat, MNI space (*.pts;*.csv)', 'INTRANAT_MNI'; ...
3675 {'.csv'}, 'EEG: Localite (*.csv)', 'LOCALITE'; ...
3676 {'.dat','.tri','.txt','.asc'}, 'EEG: Neuroscan (*.dat;*.tri;*.txt;*.asc)', 'NEUROSCAN'; ...
3677 {'.pos','.pol','.elp','.txt'}, 'EEG: Polhemus (*.pos;*.pol;*.elp;*.txt)', 'POLHEMUS'; ...
3678 {'.csv'}, 'EEG: SimNIBS (*.csv)', 'SIMNIBS'; ...
3679 {'.h5'}, 'EEG: The Virtual Brain (*_SensorsEEG.h5)', 'TVB'; ...
3680 {'*'}, 'EEG: ASCII: Name,XYZ (*.*)', 'ASCII_NXYZ'; ...
3681 {'*'}, 'EEG: ASCII: Name,XYZ_MNI (*.*)', 'ASCII_NXYZ_MNI'; ...
3682 {'*'}, 'EEG: ASCII: Name,XYZ_World (*.*)', 'ASCII_NXYZ_WORLD'; ...
3683 {'*'}, 'EEG: ASCII: Name,XY (*.*)', 'ASCII_NXY'; ...
3684 {'*'}, 'EEG: ASCII: XYZ (*.*)', 'ASCII_XYZ'; ...
3685 {'*'}, 'EEG: ASCII: XYZ_MNI (*.*)', 'ASCII_XYZ_MNI'; ...
3686 {'*'}, 'EEG: ASCII: XYZ_World (*.*)', 'ASCII_XYZ_WORLD'; ...
3687 {'*'}, 'EEG: ASCII: XY (*.*)', 'ASCII_XY'; ...
3688 {'*'}, 'EEG: ASCII: XYZ,Name (*.*)', 'ASCII_XYZN'; ...
3689 {'*'}, 'EEG: ASCII: XYZ_MNI,Name (*.*)', 'ASCII_XYZN_MNI'; ...
3690 {'*'}, 'EEG: ASCII: XYZ_World,Name (*.*)', 'ASCII_XYZN_WORLD'; ...
3691 {'*'}, 'EEG: ASCII: Name,Theta,Phi (*.*)', 'ASCII_NTP'; ...
3692 {'*'}, 'EEG: ASCII: Theta,Phi (*.*)', 'ASCII_TP'; ...
3693 };
3694 case 'channelout'
3695 argout1 = {...
3696 {'.pos'}, 'EEG+Headshape: Polhemus (*.pos)', 'POLHEMUS'; ...
3697 {'.eeg'}, 'Headshape: MegDraw (*.eeg)', 'MEGDRAW'; ...
3698 {'.pos'}, 'Headshape: Polhemus (*.pos)', 'POLHEMUS-HS'; ...
3699 {'.txt'}, 'Headshape: ASCII: XYZ (*.txt)', 'ASCII_XYZ-HS'; ...
3700 {'.txt'}, 'Headshape: ASCII: XYZ_World (*.txt)', 'ASCII_XYZ_WORLD-HS'; ...
3701 {'.txt'}, 'Headshape: ASCII: Name,XYZ (*.txt)', 'ASCII_NXYZ-HS'; ...
3702 {'.txt'}, 'Headshape: ASCII: Name,XYZ_World (*.txt)', 'ASCII_NXYZ_WORLD-HS'; ...
3703 {'.txt'}, 'Headshape: ASCII: XYZ,Name (*.txt)', 'ASCII_XYZN-HS'; ...
3704 {'.txt'}, 'Headshape: ASCII: XYZ_World,Name (*.txt)', 'ASCII_XYZN_WORLD-HS'; ...
3705 {'.sfp'}, 'EEG: BESA (*.sfp)', 'BESA-SFP'; ...
3706 {'.elp'}, 'EEG: BESA (*.elp)', 'BESA-ELP'; ...
3707 {'.tsv'}, 'EEG: BIDS electrodes.tsv, subject space mm (*.tsv)', 'BIDS-SCANRAS-MM'; ...
3708 {'.tsv'}, 'EEG: BIDS electrodes.tsv, MNI space mm (*.tsv)', 'BIDS-MNI-MM'; ...
3709 {'.xyz'}, 'EEG: Cartool (*.xyz)', 'CARTOOL-XYZ'; ...
3710 {'.res'}, 'EEG: Curry (*.res)', 'CURRY-RES'; ...
3711 {'.xyz'}, 'EEG: EEGLAB (*.xyz)', 'EEGLAB-XYZ'; ...
3712 {'.sfp'}, 'EEG: EGI (*.sfp)', 'EGI'; ...
3713 {'.txt'}, 'EEG: ASCII: XYZ (*.txt)', 'ASCII_XYZ-EEG'; ...
3714 {'.txt'}, 'EEG: ASCII: XYZ_MNI (*.txt)', 'ASCII_XYZ_MNI-EEG'; ...
3715 {'.txt'}, 'EEG: ASCII: XYZ_World (*.txt)', 'ASCII_XYZ_WORLD-EEG'; ...
3716 {'.txt'}, 'EEG: ASCII: Name,XYZ (*.txt)', 'ASCII_NXYZ-EEG'; ...
3717 {'.txt'}, 'EEG: ASCII: Name,XYZ_MNI (*.txt)', 'ASCII_NXYZ_MNI-EEG'; ...
3718 {'.txt'}, 'EEG: ASCII: Name,XYZ_World (*.txt)', 'ASCII_NXYZ_WORLD-EEG'; ...
3719 {'.txt'}, 'EEG: ASCII: XYZ,Name (*.txt)', 'ASCII_XYZN-EEG'; ...
3720 {'.txt'}, 'EEG: ASCII: XYZ_MNI,Name (*.txt)', 'ASCII_XYZN_MNI-EEG'; ...
3721 {'.txt'}, 'EEG: ASCII: XYZ_World,Name (*.txt)', 'ASCII_XYZN_WORLD-EEG'; ...
3722 {'.txt'}, 'NIRS: Brainsight (*.txt)', 'BRAINSIGHT-TXT'; ...
3723 };
3724 case 'labelin'
3725 argout1 = {...
3726 {'.dfs'}, 'BrainSuite atlas (*.dfs)', 'DFS'; ...
3727 {'.annot'}, 'FreeSurfer atlas (*.annot)', 'FS-ANNOT'; ...
3728 {'.label'}, 'FreeSurfer ROI, single scout (*.label)', 'FS-LABEL-SINGLE'; ...
3729 {'.label'}, 'FreeSurfer ROI, probability map (*.label)', 'FS-LABEL'; ...
3730 {'.gii'}, 'GIfTI texture (*.gii)', 'GII-TEX'; ...
3731 {'.dset'}, 'SUMA atlas (*.dset)', 'DSET'; ...
3732 {'_scout'}, 'Brainstorm scouts (*scout*.mat)', 'BST'; ...
3733 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (dilated, subject space)', 'MRI-MASK'; ...
3734 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (dilated, MNI space)', 'MRI-MASK-MNI'; ...
3735 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz', '_subjectimage'}, 'Volume mask or atlas (no overlap, subject space)', 'MRI-MASK-NOOVERLAP'; ...
3736 {'.mri', '.fif', '.img', '.ima', '.nii', '.mgh', '.mgz', '.mnc', '.mni', '.gz'}, 'Volume mask or atlas (no overlap, MNI space)', 'MRI-MASK-NOOVERLAP-MNI'; ...
3737 };
3738 case 'resultsout'
3739 argout1 = {...
3740 {'_sources'}, 'Brainstorm sources (*sources*.mat)', 'BST'; ...
3741 {'.mat'}, 'FieldTrip sources (*.mat)', 'FT-SOURCES'; ...
3742 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3743 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3744 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3745 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3746 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3747 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3748 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3749 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3750 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3751 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3752 };
3753 case 'timefreqout'
3754 argout1 = {...
3755 {'_timefreq'}, 'Brainstorm structure (*timefreq*.mat)', 'BST'; ...
3756 {'.mat'}, 'FieldTrip freq (*.mat)', 'FT-FREQ'; ...
3757 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3758 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3759 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3760 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3761 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3762 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3763 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3764 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3765 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3766 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3767 };
3768 case 'matrixout'
3769 argout1 = {...
3770 {'_matrix'}, 'Brainstorm structure (*matrix*.mat)', 'BST'; ...
3771 {'.mat'}, 'FieldTrip timelock (*.mat)', 'FT-TIMELOCK'; ...
3772 {'.txt'}, 'ASCII: Space-separated, fixed columns size (*.txt)', 'ASCII-SPC'; ...
3773 {'.txt'}, 'ASCII: Space-separated with header, fixed column size (*.txt)', 'ASCII-SPC-HDR'; ...
3774 {'.tsv'}, 'ASCII: Tab-separated (*.tsv)', 'ASCII-TSV'; ...
3775 {'.tsv'}, 'ASCII: Tab-separated with header (*.tsv)', 'ASCII-TSV-HDR'; ...
3776 {'.tsv'}, 'ASCII: Tab-separated with header transposed (*.tsv)', 'ASCII-TSV-HDR-TR'; ...
3777 {'.csv'}, 'ASCII: Comma-separated (*.csv)', 'ASCII-CSV'; ...
3778 {'.csv'}, 'ASCII: Comma-separated with header (*.csv)', 'ASCII-CSV-HDR'; ...
3779 {'.csv'}, 'ASCII: Comma-separated with header transposed (*.csv)', 'ASCII-CSV-HDR-TR'; ...
3780 {'.xlsx'}, 'Microsoft Excel (*.xlsx)', 'EXCEL'; ...
3781 {'.xlsx'}, 'Microsoft Excel transposed (*.xlsx)', 'EXCEL-TR'; ...
3782 };
3783 case 'montagein'
3784 argout1 = {...
3785 {'.sel'}, 'MNE selection files (*.sel)', 'MNE'; ...
3786 {'.mon'}, 'Text montage files (*.mon)', 'MON'; ...
3787 {'_montage'}, 'Brainstorm montage files (montage_*.mat)', 'BST';
3788 {'.csv'}, 'Comma-separated montage files (*.csv)', 'CSV'; ...
3789 {'.xml'}, 'Compumedics ProFusion montages (*.xml)', 'EEG-COMPUMEDICS-PFS'};
3790 case 'montageout'
3791 argout1 = {...
3792 {'.sel'}, 'MNE selection files (*.sel)', 'MNE'; ...
3793 {'.mon'}, 'Text montage files (*.mon)', 'MON'; ...
3794 {'_montage'}, 'Brainstorm montage files (montage_*.mat)', 'BST'};
3795 case 'fibers'
3796 argout1 = {...
3797 {'.trk'}, 'TrackVis (*.trk)', 'TRK'; ...
3798 {'_fibers'}, 'Brainstorm fibers files (fibers_*.mat)', 'BST'};
3799 end
3800
3801
3802 %% ===== FONTS =====
3803 case 'FigFont'
3804 if ispc
3805 argout1 = 8;
3806 else
3807 argout1 = 9;
3808 end
3809 InterfaceScaling = bst_get('InterfaceScaling');
3810 if (InterfaceScaling ~= 100)
3811 argout1 = argout1 * InterfaceScaling / 100;
3812 end
3813
3814 case 'Font'
3815 % Default font size
3816 if (nargin < 2)
3817 if strncmp(computer,'MAC',3)
3818 fontSize = 12;
3819 else
3820 fontSize = 11;
3821 end
3822 % Font size in input
3823 else
3824 fontSize = varargin{2};
3825 end
3826 % Adjust for interface scaling
3827 fontSize = fontSize * bst_get('InterfaceScaling') / 100;
3828
3829 % Font types
3830 fontTypes = {};
3831 if (nargin >= 3)
3832 fontTypes{end + 1} = varargin{3};
3833 end
3834 fontTypes{end + 1} = 'Arial'; % Default font
3835 fontTypes{end + 1} = 'Liberation Sans'; % Free Arial substitute
3836
3837 % Check for cached font
3838 foundFont = 0;
3839 for iFont = 1 : length(fontTypes)
3840 strCache = strrep(sprintf('%s%d', fontTypes{iFont}, round(fontSize*100)), ' ', '_');
3841 if ~isempty(GlobalData) && isfield(GlobalData, 'Program') && isfield(GlobalData.Program, 'FontCache') && isfield(GlobalData.Program.FontCache, strCache)
3842 argout1 = GlobalData.Program.FontCache.(strCache);
3843 foundFont = 1;
3844 break;
3845 end
3846 end
3847
3848 % If font not cached, find first supported font
3849 if ~foundFont
3850 ge = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
3851 allFonts = cell(ge.getAvailableFontFamilyNames());
3852
3853 for iFont = 1 : length(fontTypes)
3854 if any(strcmp(fontTypes{iFont}, allFonts))
3855 fontType = fontTypes{iFont};
3856 foundFont = 1;
3857 break;
3858 end
3859 end
3860
3861 if ~foundFont
3862 fontType = 'SansSerif'; % If nothing else works.
3863 end
3864
3865 strCache = strrep(sprintf('%s%d', fontType, round(fontSize*100)), ' ', '_');
3866 argout1 = java.awt.Font(fontType, java.awt.Font.PLAIN, fontSize);
3867 GlobalData.Program.FontCache.(strCache) = argout1;
3868 end
3869
3870 %% ==== PANEL CONTAINERS ====
3871 case 'PanelContainer'
3872 % Get Brainstorm GUI context structure
3873 bst_GUI = GlobalData.Program.GUI;
3874 if (isempty(bst_GUI) || ~isfield(bst_GUI, 'panelContainers'))
3875 error('Brainstorm GUI is not yet initialized');
3876 end
3877
3878 % Get ContainerName in argument
3879 if ((nargin >= 2) && (ischar(varargin{2})))
3880 ContainerName = varargin{2};
3881 % If no container name in argument : just display all the container names
3882 else
3883 disp('Registered panel containers :');
3884 for iContainer = 1:length(bst_GUI.panelContainers)
3885 disp([' - ' bst_GUI.panelContainers(iContainer).name]);
3886 end
3887 return
3888 end
3889
3890 % Look for containerName in all the registered panel containers
3891 iContainer = 1;
3892 found = 0;
3893 while (~found (iContainer <= length(bst_GUI.panelContainers)))
3894 if (strcmpi(ContainerName, bst_GUI.panelContainers(iContainer).name))
3895 found = 1;
3896 else
3897 iContainer = iContainer + 1;
3898 end
3899 end
3900 % If container is found : return it
3901 if (found)
3902 argout1 = bst_GUI.panelContainers(iContainer).jHandle;
3903 else
3904 % warning('Brainstorm:InvalidContainer', 'Container ''%s'' could not be found.', ContainerName);
3905 end
3906
3907
3908 %% ==== PANELS ====
3909 case 'Panel'
3910 % Get Brainstorm GUI context structure
3911 if (isempty(GlobalData) || isempty(GlobalData.Program.GUI) || ~isfield(GlobalData.Program.GUI, 'panels'))
3912 return
3913 end
3914 listPanels = GlobalData.Program.GUI.panels;
3915 % Get Panel in argument
3916 if ((nargin >= 2) && (ischar(varargin{2})))
3917 PanelName = varargin{2};
3918 % If no panel name in argument : just display all the panels names
3919 else
3920 disp('Registered panels :');
3921 for iContainer = 1:length(listPanels)
3922 disp([' - ' get(listPanels(iContainer), 'name')]);
3923 end
3924 return
3925 end
3926 % Look for panelName in all the registered panels
3927 iPanel = find(strcmpi(PanelName, get(listPanels, 'name')), 1);
3928 if ~isempty(iPanel)
3929 argout1 = listPanels(iPanel);
3930 argout2 = iPanel;
3931 end
3932
3933
3934 %% ==== PANEL CONTROLS ====
3935 % Calls : bst_get('PanelControls', PanelName)
3936 case 'PanelControls'
3937 % Get Panel name in argument
3938 if ((nargin >= 2) && (ischar(varargin{2})))
3939 PanelName = varargin{2};
3940 else
3941 error('Invalid call to bst_get()');
3942 end
3943 % Find BstPanel with this name
3944 bstPanel = bst_get('Panel', PanelName);
3945 % If panel was found : return its controls
3946 if ~isempty(bstPanel)
3947 argout1 = get(bstPanel, 'sControls');
3948 end
3949
3950 %% ===== NODES COPY =====
3951 % Calls : bst_get('Clipboard')
3952 case 'Clipboard'
3953 argout1 = GlobalData.Program.Clipboard.Nodes;
3954 argout2 = GlobalData.Program.Clipboard.isCut;
3955
3956 %% ==== DIRECTORIES ====
3957 case 'DirDefaultSubject'
3958 argout1 = '@default_subject';
3959 case 'DirDefaultStudy'
3960 argout1 = '@default_study';
3961 case 'DirAnalysisIntra'
3962 argout1 = '@intra';
3963 case 'DirAnalysisInter'
3964 argout1 = '@inter';
3965 case 'NormalizedSubjectName'
3966 argout1 = 'Group_analysis';
3967
3968 %% ==== OTHER ====
3969 case 'ResizeFunction'
3970 if (bst_get('MatlabVersion') <= 803)
3971 argout1 = 'ResizeFcn';
3972 else
3973 argout1 = 'SizeChangedFcn';
3974 end
3975 case 'groot'
3976 if (bst_get('MatlabVersion') <= 803)
3977 argout1 = 0;
3978 else
3979 argout1 = groot;
3980 end
3981 case 'JFrame'
3982 hFig = varargin{2};
3983 MatlabVersion = bst_get('MatlabVersion');
3984 jFrame = [];
3985 try
3986 if (MatlabVersion <= 705)
3987 jf = get(hFig, 'javaframe');
3988 jFrame = jf.fFigureClient.getWindow();
3989 elseif (MatlabVersion <= 712)
3990 jf = get(handle(hFig), 'javaframe');
3991 jFrame = jf.fFigureClient.getWindow();
3992 elseif (MatlabVersion <= 803)
3993 jf = get(handle(hFig), 'javaframe');
3994 jFrame = jf.fHG1Client.getWindow();
3995 elseif (MatlabVersion < 907) % Matlab >= 2019b deprecated the JavaFrame property
3996 warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
3997 jf = get(hFig, 'javaframe');
3998 warning('on', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
3999 jFrame = jf.fHG2Client.getWindow();
4000 else
4001 disp('BST> Error: Matlab 2019b deprecated the JavaFrame property.');
4002 end
4003 catch
4004 disp('BST> Warning: Cannot get the JavaFrame property for the selected figure.');
4005 end
4006 argout1 = jFrame;
4007
4008 %% ==== ERROR ====
4009 otherwise
4010 error(sprintf('Invalid context : "%s"', contextName));
4011 end
4012 end
4013
4014
4015
4016
4017 %% ==== HELPERS ====
4018 % Return all the protocol studies that have a given file in its structures
4019 % Possible field names: Result.DataFile, Result.FileName, Data.FileName, Channel.FileName
4020 %
4021 % USAGE: [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile, iStudiesList)
4022 % [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile)
4023 function [sFoundStudy, iFoundStudy, iItem] = findFileInStudies(fieldGroup, fieldName, fieldFile, iStudiesList)
4024 global GlobalData;
4025 sFoundStudy = [];
4026 iFoundStudy = [];
4027 iItem = [];
4028 % If no file provided, return
4029 if isempty(fieldFile)
4030 return;
4031 end
4032 % Extract folder(s) of the file(s) we're looking for
4033 fieldParts = strfind(fieldFile, '|');
4034 if ~isempty(fieldParts)
4035 fieldParts(end+1) = length(fieldFile);
4036 fieldFolders = {};
4037 iLast = 1;
4038 for iPart = 1:length(fieldParts)
4039 folder = fileparts(fieldFile(iLast:fieldParts(iPart)-1));
4040 if ~isempty(folder)
4041 fieldFolders{end + 1} = folder;
4042 end
4043 iLast = fieldParts(iPart) + 1;
4044 end
4045 else
4046 fieldFolders = {fileparts(fieldFile)};
4047 end
4048 % Get protocol information
4049 ProtocolStudies = GlobalData.DataBase.ProtocolStudies(GlobalData.DataBase.iProtocol);
4050 % List studies to process
4051 if (nargin < 4) || isempty(iStudiesList)
4052 iStudiesList = [-2, -3, 1:length(ProtocolStudies.Study)];
4053 end
4054
4055 % NORMAL STUDIES: Look for surface file in all the surfaces of all subjects
4056 for iStudy = iStudiesList
4057 % Get study
4058 switch (iStudy)
4059 case -2, sStudy = ProtocolStudies.AnalysisStudy;
4060 case -3, sStudy = ProtocolStudies.DefaultStudy;
4061 otherwise, sStudy = ProtocolStudies.Study(iStudy);
4062 end
4063 % Check if field is available for the study
4064 if isempty(sStudy.(fieldGroup))
4065 continue;
4066 end
4067 % Check we are in the correct folder
4068 if ~any(file_compare(fieldFolders, fileparts(sStudy.FileName)))
4069 continue;
4070 end
4071 % Get list of files from study
4072 filesList = {sStudy.(fieldGroup).(fieldName)};
4073 if isempty(filesList)
4074 continue;
4075 end
4076 % Replace empty cells with empty strings
4077 iValidFiles = find(cellfun(@ischar, filesList));
4078 if isempty(iValidFiles)
4079 continue;
4080 end
4081 % Find target in this list
4082 iItem = find(file_compare(filesList(iValidFiles), fieldFile));
4083 if ~isempty(iItem)
4084 sFoundStudy = sStudy;
4085 iFoundStudy = iStudy;
4086 iItem = iValidFiles(iItem);
4087 return
4088 end
4089 end
4090 end
4091
4092
4093 %% ===== FILL MISSING FIELDS =====
4094 function bstPref = FillMissingFields(PrefName, defPref)
4095 global GlobalData;
4096 if isfield(GlobalData, 'Preferences') && isfield(GlobalData.Preferences, PrefName)
4097 bstPref = GlobalData.Preferences.(PrefName);
4098 bstPref = struct_copy_fields(bstPref, defPref, 0);
4099 else
4100 bstPref = defPref;
4101 end
4102 end
4103
4104
4105
4106
4107
4108
4109
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) 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', 'ConnectGraphOptions', '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 % Default domain: plot.ly
275 if isempty(domain)
276 domain = 'https://plot.ly';
277 end
278 % Plotly needs a URL with HTTP and no trailing slash.
279 if strfind(domain, 'https://')
280 domain = strrep(domain, 'https://', 'http://');
281 elseif isempty(strfind(domain, 'http://'))
282 domain = ['http://', domain];
283 end
284 if domain(end) == '/'
285 domain = domain(1:end-1);
286 end
287 % Save credentials
288 saveplotlycredentials(username, apiKey);
289 saveplotlyconfig(domain);
290
291 %% ==== ERROR ====
292 otherwise
293 error('Invalid context : ''%s''', contextName);
294
295
296 end
297
298
299
300
File structures
The structures of the different types of files functions were described in the sections "On the hard drive" of the introduction tutorials. Here is a directory 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.
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 from the Brainstorm database 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_bst_data(DataFile): Read an imported epoch.
in_bst_timefreq(TimefreqFile): Read a power spectrum, time-frequency or connectivity 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. Require 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: Must be an absolute path, use in combination with file_fullpath to use relative paths.
FileMat: Must be a 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, only updates the fields that are defined in FileMat, keep the others untouched.
Registering new files in the database:
db_add()
Reload folders (if you saved or deleted new files without registering the modifications 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).
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
Export the contents of a figure to a file:
out_figure_
Plot file contents:
view_
Other db_ functions
Code examples
Example:
Example: Creating a new file
(explain the reloading)
Example: Edit events
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 "File files" (or Ctrl+Shift+F), enter the name of function your are looking for 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 Brainstorm. 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, for example
Debugger
Additional quality control [TODO]
Create figures and snapshot them
Generate warnings and errors
Loop over subject and runs [TODO]
Creating loops is not supported yet by the script generator, but relatively easy to do from a script without having to know too much about Matlab programming.
1) Fill the cell array SubjectNames with all your subjects names, with the same dimensions as the list of input raw files (sFiles)
2) Add a "for" loop that includes all the bst_process() calls (leave the bst_report() calls and input definition outside)
3) Inside the loop, replace SubjectNames with SubjectNames{i} and sFiles with sFiles(i)
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 script
The following script from the Brainstorm distribution reproduces the introduction tutorials ("Get started"): brainstorm3/toolbox/script/tutorial_introduction.m - Report: report_TutorialIntroduction.html