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