Setting subject individual anatomy in a script

Hi,

I'm setting many subjects' individual anatomy by importing their MRIs. I do this after having first worked on a template brain for a while, so I have a lot of data, but simply a tree branch to default anatomy in the protocol tree.
Then I plan to scroll through all SubjectNames and import the newly found MRIs stored in RawFiles

for i_sub = 1:numel(SubjectNames)
    sFiles = [];

    % Process: Import MRI
    sFiles = bst_process('CallProcess', 'process_import_mri', sFiles, [], ...
        'subjectname', SubjectNames{i_sub}, ...
        'mrifile',     {RawFiles{i_sub}, 'Nifti1'}, ...
        'nas',         [0, 0, 0], ...
        'lpa',         [0, 0, 0], ...
        'rpa',         [0, 0, 0], ...
        'ac',          [0, 0, 0], ...
        'pc',          [0, 0, 0], ...
        'ih',          [0, 0, 0]);

end

However, when I do this with my first subject, it imports the mri, but the subject in the tree is still marked "use protocol's default anatomy".
If I click on this subject and hover over its name for a while, the renamed selection that appears says "@default_subject". It looks like this after accepting this default and renaming the subject involuntarily.

image

When I look at the files on disk, I see this (sub-75control being the subject I actually just imported)

image

All files below the brainstormsubject.mat file in @default_subject are older files that were copied from I don't know where...

What did I do wrong?

If I understand correctly, your subjects were initially created using the option "Default anatomy: Yes", and now you are trying to import additional anatomical information on the same subject
Have you changed the configuration of the subjects before trying to add new files to them?
Note that this is not recommended if you have already imported data for these subjects: the positions of the sensors are defined with respect to the NAS/LPA/RPA points of the MRI, and the registration MRI-sensors would most likely be wrong after changing the anatomy. Additionally, all the source-level results must be deleted and recomputed.

It looks like this after accepting this default and renaming the subject involuntarily.

I don't understand this. How can you end up having a folder that appears as @default_subject instead of (Default anatomy) in the database explorer. Do you have an other folder @default_subject in the database than the one in /anat/@default_subject ?
Can you please describe better in which context you got offered to rename a subject into "@default_anatomy"?

When I look at the files on disk, I see this (sub-75control being the subject I actually just imported)

Nothing is wrong on this end.
Except that it's not such a good idea to save personal files that do not belong to the Brainstorm database into the anatomy folders (cluster_...mat).

All files below the brainstormsubject.mat file in @default_subject are older files that were copied from I don't know where...

If they were not already in the default anatomy of this protocol, they have been copied from the default anatomy in Brainstorm: brainstorm3/defaults/anatomy/ICBM152
Note that the Brainstorm MNI ICBM152 template has been updated recently, to include updated surfaces and new volume and surface parcellations. Do not update the default anatomy in an existing protocol, as it would break all the source results computed from the old surfaces.

Have you changed the configuration of the subjects before trying to add new files to them?

No, I must confess :sweat_smile:

But no source level results were computed yet. Only sensor level analyses have been done so far.

I don't understand this. How can you end up having a folder that appears as @default_subject instead of (Default anatomy) in the database explorer. Do you have an other folder @default_subject in the database than the one in /anat/@default_subject ?

No I don't. But then it created one in my data/ folder...

Can you please describe better in which context you got offered to rename a subject into "@default_anatomy"?

Quite mysteriously, just after running this line of the script:

    sFiles = bst_process('CallProcess', 'process_import_mri', sFiles, [], ...
        'subjectname', SubjectNames{i_sub}, ...
        'mrifile',     {RawFiles{i_sub}, 'Nifti1'}, ...
        'nas',         [0, 0, 0], ...
        'lpa',         [0, 0, 0], ...
        'rpa',         [0, 0, 0], ...
        'ac',          [0, 0, 0], ...
        'pc',          [0, 0, 0], ...
        'ih',          [0, 0, 0]);

Seeing that nothing happened in the protocol tree, I clicked and hovered over the name of the subject for a second, the interface suggested renaming the subject (this is usually showing a text selection with the name of the subject in it). The selected text that appeared this time in that subject didn't include the name of the subject, but the string "@default_subject". Validating this eventually renamed my subject to "@default_subject". No idea how this "@default_subject" value appeared here. After that, it created a @default_subject in the data folder (perhaps after asking for confirmation, I'm not sure anymore).

I realize that this whole mess is due to the fact that Brainstorm is still expecting that this subject has no anatomy.

Is there a way to programmatically change subjects from 'use default anatomy' to 'use individual anatomy'?

I see, I reproduce what you did: after calling process_import_mri on a subject using the default anatomy, the database gets out of control...
I added tests to prevent people to do this again: Bugfix: Forbid adding anatomy files to subjects using the default anat · brainstorm-tools/brainstorm3@7aa8098 · GitHub

The follow-up errors are marginal problems due to this initial mistake, so I'm not going to try to debug the renaming of the subject. I hope you'll find a way to fix your database...

Is there a way to programmatically change subjects from 'use default anatomy' to 'use individual anatomy'?

Something like that should work:

[sSubject, iSubject] = bst_get('Subject', SubjectName, 1);
sSubject.UseDefaultAnat = 0;
sSubject.FileName = [sSubject.Name, '/brainstormsubject.mat'];
db_add_subject(sSubject, iSubject);
1 Like

sSubject.FileName = [sSubject.Name, '/brainstormsubject.mat']; db_add_subject(sSubject, iSubject);

Thanks, indeed, without that piece, my protocol was collapsing! using bst_set(sSubject, iSubject) wasn't the good way to go, I guess.

I'll try that next time.

If I were to create a subject from scratch entirely, that would be the way to go, right?
Creating a proper sSubject structure and adding it to the db with db_add_subject(sSubject, iSubject);

Thanks!

It was not, as bst_set('Subject, ...') is used to interact only with Brainstorm DB in memory (not with files in HDD).

Yes, for adding a new subject, you can omit the iSubject argument. To see the new subject in the GUI it's necessary to also update the tree:

[sSubject, iSubject] = db_add_subject('A_new_subject ', [], UseDefaultAnat, UseDefaultChannel);
panel_protocols('UpdateTree'); % Update the Protocol in GUI
1 Like