Runing bst in singularity

Hi!

I'm having some issue when I try to run brainstorm through singularity.

This is the script I'm trying to run (main2.m):

disp('0) My script has started');

%% Key paths
% Directory to store brainstorm database
BrainstormDbDir = [pwd, '/brainstorm_db/']; % Full path
ReportsDir = pwd;

%% Parameters
% Path to the data
sFilesMEG = '/Users/guiomar/Downloads/meg.fif';

ProtocolName = 'Protocol01'; % Needs to be a valid folder name (no spaces, no weird characters, etc)
SubjectName = 'Subject01';

% NOTCH FILTER
% Frequencies to filter with the noth (e.g. power line 60Hz and harmonics)
freqs_notch = 60:60:60;

% LOW AND HIGH PASS FILTER
highpass = 0.3;
lowpass = 0; % 0: no filter

% PSD
% Window length and overlap for PSD Welch method
win_length = 4; % seconds
win_overlap = 0; % percentage

%% START BRAINSTORM
disp('== Start Brainstorm defaults');

% Set Brainstorm database directory
bst_set('BrainstormDbDir',BrainstormDbDir) 
% Reset colormaps
bst_colormaps('RestoreDefaults', 'meg');

%%%%%%%%
% See Tutorial 1
disp(['- BrainstormDbDir:', bst_get('BrainstormDbDir')]);
disp(['- BrainstormUserDir:', bst_get('BrainstormUserDir')]); % HOME/.brainstom (operating system)
disp(['- HOME env:', getenv('HOME')]);
disp(['- HOME java:', char(java.lang.System.getProperty('user.home'))]);
%%%%%%%%

%% CREATE PROTOCOL 
disp('== Create protocol');

% Create new protocol
UseDefaultAnat = 1; 
UseDefaultChannel = 0;
gui_brainstorm('CreateProtocol', ProtocolName, UseDefaultAnat, UseDefaultChannel);

disp('- New protocol created');

%% ==== 1) Import MEG files =======================================
disp('== 1) Import MEG file');

sFiles0 = [];
% Start a new report
bst_report('Start');

% Process: Create link to raw file    
sFiles = bst_process('CallProcess', 'process_import_data_raw', ...
    sFiles0, [], ...
    'subjectname', SubjectName, ...
    'datafile', {sFilesMEG, 'FIF'}, ...
    'channelreplace', 1, ...
    'channelalign', 1);

%% ==== 2) PSD on sensors (before filtering) ======================

disp('== 2) PSD on sensors');

% Process: Power spectrum density (Welch)
sFilesPSDpre = bst_process('CallProcess', 'process_psd', ...
    sFiles, [], ...
    'timewindow', [], ...
    'win_length', win_length, ...
    'win_overlap', win_overlap, ...
    'sensortypes', 'MEG, EEG', ...
    'edit', struct(...
         'Comment', 'Power', ...
         'TimeBands', [], ...
         'Freqs', [], ...
         'ClusterFuncTime', 'none', ...
         'Measure', 'power', ...
         'Output', 'all', ...
         'SaveKernel', 0));

%% ==== 3)  Notch filter =====================

disp('== 3) Notch');

% Process: Notch filter: 
sFilesNotch = bst_process('CallProcess', 'process_notch', ...
    sFiles, [], ...
    'freqlist', freqs_notch, ...
    'sensortypes', 'MEG, EEG', ...
    'read_all', 0); 

%% ==== 4)  High pass filter =====================

disp('== 4) Highpass');

% Process: High-pass:
sFiles = bst_process('CallProcess', 'process_bandpass', ...
    sFiles, [], ...
    'highpass', highpass, ...
    'lowpass', lowpass, ...
    'mirror', 1, ...
    'sensortypes', 'MEG, EEG', ...
    'read_all', 0);

%% Save Report and delete protocol

% Save report
disp('== Save report');
ReportFile = bst_report('Save', []);
bst_report('Export', ReportFile, ReportsDir);

% Delete existing protocol
gui_brainstorm('DeleteProtocol', ProtocolName);
disp('== Delete protocol');

%% DONE
disp('** Done!');

I can sucessfully run it locally wit matlab mrc:

/Users/guiomar/Documents/SOFTWARE/brainstorm3/bin/R2020a/brainstorm3.command /Applications/MATLAB/MATLAB_Runtime/v98 main2.m local

However, when I try this:

singularity run -e --bind `pwd`/home:/home/$USER docker://brainlife/brainstorm:220526 main2.m local

Nor of the processes notch or bandpass run properly. On the report it says:

This file has been moved, deleted, is used by another program,
or is on a drive that is currently not connected to your computer

I wonder why, if this is the exact same code on both. And if the input parameters for the psd (which runs fine on both) and for the notch and bandpass processes (which give error in singularity) are the same (sFiles).

Could you reproduce the error? Any clue of what could be going on?

Thanks!

Your script looks good, except for the fact that you apply separately the notch and the bandpass (which is executed from sFiles and not sFilesNotch.

If the same script works locally but not a distance, it probably not your script main2.m that is to blame. Possible issues:

  • the paths are not defined correctly in your singularity execution
  • the access writes to the database are not set correctly, or there are mounting/locking mechanisms that are not compatible with the way Brainstorm works
  • your script is not called correctly (parameters not set correctly)
  • there are issues with executing Matlab from singularity?

We have no experience with Singularity or Docker, I'm sorry we won't be able to help you much here...

Please post your findings here, to help future users.
If you find interesting solutions, it could be also interesting to add a link to this thread in this tutorial: Tutorials/Scripting - Brainstorm

PS:
freqs_notch = 60:60:60;
Returns only 60. Is this working as expected?

Thank you François!

Yes, I have sFiles as an input for the three processes: psd, notch and bandpass, just to ensure which ones were failing (psd is done properly, not notch and bandpass).
Also had the frequencies for the notch set to only 60Hz, to reduce computing time in this example.

I'm not very expert using containers either, but I'm very intrigued why it could create the brainstorm_db with the protocol, link the raw, create the associated folder, compute the psd (with sFiles as an input) and write the results in the apropriate folder, and then fail to access sFiles for the notch and bandpass processes.

Have you, or anyone you know tried to run bst in a container?

@soichih I ping you in the thread in case you could provide any other info.

Thanks!

Are you sure the .bst files from the notch and bandpass filters are executed correctly?
=> After the call: print sFilesNotch.FileName and print the list of files in this folder. Maybe the creation of a new raw file doesn't work, because of paths not handled correctly?

Have you, or anyone you know tried to run bst in a container?

@SpagnaPhd @DNAcombo @ncasati
Do you know if anybody has ever tried to do something like this ?

sFilesNotch is empty, it doesn't get to run the process, probably due to sFiles not being accesible. Since sFiles hasen't been modified from the call of the psd process and in the psd it could be reached properly, I don't know what it could be.

This is the message it returns in the report:

[Subject01/@rawmeg/data_0raw_meg.mat] -->

This file has been moved, deleted, is used by another program,
or is on a drive that is currently not connected to your computer

And this are the files available in the database with their permissions:

Maybe is a problem with the permissions of data_0raw_meg.mat, but then how is the psd process being able to run properly?

I think you need to add a lot more debugging code in your script...
Do you have access to the stdout from the execution of the script?
If so, you can explore the database and the file system from your script and print a lot of output text, in order to know what is seen from the container at the execution time. Check both the existence and the files and their rights from the very script (as they may differ from what you see in your management interface).

The Scripting tutorial contains lots of examples.
https://neuroimage.usc.edu/brainstorm/Tutorials/Scripting

We run it through docker and it works!