Issue activating a newly created subject from Python

Dear Brainstorm Team,

I am currently trying to create a new protocol and subject by calling Brainstorm functions from Python, but I have encountered some issues when attempting to activate the subject.

I have successfully created and activated the protocol, and then added a new subject using:

self.eng.eval(f"db_add_subject('{subject_name}');", nargout=0)

However, I have not found a reliable way to correctly activate the subject so that the files I will import next are correctly associated with it.

I found this function:

bst_set('Subject', iSubject, sSubject) 

which I thought could work, but I have not been able to obtain sSubject or iSubject.

When I try:

sSubject, iSubject = self.eng.bst_get('Subject', 'SubjectName', nargout=2)

it returns an invalid (empty) result.

Also, in my code, the function:

ProtocolInfo = self.eng.bst_get('ProtocolInfo')

works correctly, but when I try to run

ProtocolSubjects = self.eng.bst_get('ProtocolSubjects')

it raises the error: ““Only struct can be returned from MATLAB.”

Could you please help me find the proper way to activate the subject?

Thank you very much for your help,
Claudia

Hi Claudia,

Please carefully read the scripting tutorial, even when all the examples are in Matlab, you can call the exactly same functions using the MATLAB Engine API for Python

I'd strongly suggest you to write first the Matlab script, test it and make it work properly. This will allow you to use the Matlab debugger to find the find and fix errors like the ones reported, use as example the more dozens of pipelines that we provide as scripts:

brainstorm3/toolbox/script at master · brainstorm-tools/brainstorm3 · GitHub

Once the Matlab code is ready, then you mostly need copy-paste it into Python, or even easier, just call that script from Python as:

self.eng.my_wonderfil_script()



Do not use eval it is not recommended, it is less efficient and code is harder to debug.
https://www.mathworks.com/help/matlab/ref/eval.html

Check the scripting tutorial. bst_set('Subject', iSubject, sSubject) is used to update the sSubject structure.

Are you sure that 'SubjectName' already exist in the database?

This is an error that comes from the MATLAB Engine API for Python.
Are you sure Brainstorm is running when running this line?

This is done with db_add_subject(), listed in here:
https://neuroimage.usc.edu/brainstorm/Tutorials/Scripting#Reference:_File_manipulation

You can search for its use in the provided scripted pipelines:
Code search results · GitHub

Hi Raymundo,

Ok, thank you for your tip.

I added the subject using the db_add_subject function, and I am importing the different files into the subject folder. Is this enough for it to exist in the database?

Also, I had a question regarding the process_import_data_raw function. I tried to run the following code in MATLAB, but it keeps returning an empty output. I have tried different solutions but nothing seems to work.

output = bst_process('CallProcess', 'process_import_data_raw', [], [\], ...
    'subjectname', SubjectName, ...
    'datafile', {{ eeg_file, 'EEG-EDF+' }}, ...
    'channelreplace', 1, ...
    'channelalign', 1);

Is there a better way to import an eeg file with .edf format ?

Thank you,

Claudia

With " I am importing the different files into the subject folder" do you mean the directory in the HDD or the Subject node in the Brainstorm DB (GUI)? If the first one, no it is not enough. Files must be added to the database using the API functions described in the Scripting tutorial. This is needed as files are saved with information that links them to other files. Some functions to import MRI and surfaces are:

import_mri()       % Add MRI / CT / PET volumes to a given Subject
import_surfaces()  % Add Surfaces to a given Subject

There are two errors:

  1. The file format, it should be 'EEG-EDF'.
  2. The value for datafile is {{file}, format}
    Thus it should be:
'datafile', {{eeg_file}, 'EEG-EDF'}, ...

P.S. You can write code in the forum post (using Markdown) by using as code fence 3 backtikcs:

```
 YOUR CODE IN HERE
```

Hi Raymundo,

By subject folder, I mean the folder named after the subject, located inside the protocol folder, which in turn is inside the brainstorm_db directory on my local computer. In every function I use to import data, I specify the path as: Home/brainstorm_db/protocol_name/subject_name/... (either data or anat, depending on whether it is EEG or MRI data).

I am not opening the Brainstorm GUI because I am developing a Python script that operates independently, without requiring MATLAB or the Brainstorm graphical interface.

Is the way I’m doing it correct?

Regarding the process_import_data_raw function, the solution you gave me worked perfectly, thank you!

Keep in mind that your original (raw) files should not be in the same directory that the protocol. As this protocol directory must be handled only by Brainstorm.

We do understand this. However Brainstorm is developed in Matlab and it is expected to run in there. This is why debugging your Python code is being difficult for you as this approach obscures the error messages displayed in Matlab. Apologies for being repetitive

Okay, thank you!