How to set up a heuristic file¶
This tutorial prepares an heuristic file to process general phys2bids
inputs.
Anatomy of a heuristic file¶
Let’s have a look under the hood of the heuristic files used in the tutorial.
It’s the file heur_tutorial.py
in phys2bids/phys2bids/heuristics/
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | import fnmatch
def heur(physinfo, run=''):
"""
Set of if .. elif statements to fill BIDS names.
It requires the user (you!) to adjust it accordingly!
It needs an ``if`` or ``elif`` statement for each file that
needs to be processed.
The statement will test if the ``physinfo``:
- is similar to a string (first case), or
- exactly matches a string (second case).
Parameters
----------
physinfo: str
Name of an input file that should be bidsified (See Notes)
Returns
-------
info: dictionary of str
Dictionary containing BIDS keys
Notes
-----
The `if ..` structure should always be similar to
```
if physinfo == 'somepattern':
info['var'] = 'somethingelse'
```
or, in case it's a partial match
```
if fnmatch.fnmatchcase(physinfo, '*somepattern?'):
info['var'] = 'somethingelse'
```
Where:
- `physinfo` and `info` are dedicated keywords,
- 'somepattern' is the name of the file,
- 'var' is a bids key in the list below
- 'somethingelse' is the value of the key
"""
info = {}
# ################################# #
# ## Modify here! ## #
# ## ## #
# ## Possible variables are: ## #
# ## -info['task'] (required) ## #
# ## -info['run'] ## #
# ## -info['rec'] ## #
# ## -info['acq'] ## #
# ## -info['dir'] ## #
# ## ## #
# ## Remember that they are ## #
# ## dictionary keys ## #
# ## See example below ## #
# ################################# #
if fnmatch.fnmatchcase(physinfo, '*tutorial*'):
info['task'] = 'test'
info['run'] = '01'
info['rec'] = 'labchart'
elif physinfo == 'Example':
info['task'] = 'rest'
info['run'] = '01'
info['acq'] = 'resp'
# ############################## #
# ## Don't modify below this! ## #
# ############################## #
return info
|
We can split this file into three parts: the initialisation, the dictionaries, and the functional code.
Initialisation¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import fnmatch
def heur(physinfo, run=''):
"""
Set of if .. elif statements to fill BIDS names.
It requires the user (you!) to adjust it accordingly!
It needs an ``if`` or ``elif`` statement for each file that
needs to be processed.
The statement will test if the ``physinfo``:
- is similar to a string (first case), or
- exactly matches a string (second case).
Parameters
----------
physinfo: str
Name of an input file that should be bidsified (See Notes)
Returns
-------
info: dictionary of str
Dictionary containing BIDS keys
Notes
-----
The `if ..` structure should always be similar to
```
if physinfo == 'somepattern':
info['var'] = 'somethingelse'
```
or, in case it's a partial match
```
if fnmatch.fnmatchcase(physinfo, '*somepattern?'):
info['var'] = 'somethingelse'
```
Where:
- `physinfo` and `info` are dedicated keywords,
- 'somepattern' is the name of the file,
- 'var' is a bids key in the list below
- 'somethingelse' is the value of the key
"""
info = {}
|
It’s important not to modify this part of the file. Instead, you can copy and paste it into your own heuristic file.
This file looks like a python function, initialised by a mandatory parameter, physinfo
.
| physinfo
is the information used to label your file. At the moment, it corresponds to the name of the input file itself. This is what you need to build your heuristic.
The function initialises info
, a python dictionary that contains the BIDS keys, such as sub and ses, as well as all the possible keys you can add to your heuristics. This is what you will work with in creating your heuristic.
The scripts also imports fnmatch
, a nice python module that lets you use bash-like wildcards.
Dictionaries¶
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # ################################# #
# ## Modify here! ## #
# ## ## #
# ## Possible variables are: ## #
# ## -info['task'] (required) ## #
# ## -info['run'] ## #
# ## -info['rec'] ## #
# ## -info['acq'] ## #
# ## -info['dir'] ## #
# ## ## #
# ## Remember that they are ## #
# ## dictionary keys ## #
# ## See example below ## #
# ################################# #
if fnmatch.fnmatchcase(physinfo, '*tutorial*'):
info['task'] = 'test'
info['run'] = '01'
info['rec'] = 'labchart'
elif physinfo == 'Example':
info['task'] = 'rest'
info['run'] = '01'
info['acq'] = 'resp'
|
if .. elif .. else
statement..if
or elif
statement for each file that you want to process, that will test if the physinfo
is similar to a string (first case) or exactly matches a string (second case). The content of the statement is a set of variable initialisations as a string, with the only difference that you’re populating a dictionary here. This means that instead of declaring something like var = 'something'
, you will declare something like info['var'] = 'something'
task
stands for the name of the task. It’s the only required entity, and it should match the task of the neuroimaging file associated to the physiological data. If this is missing the program will stop running.run
is the optional entity for the index of the scan in a group of same modalities (e.g. 2 resting states).rec
is the optional entity for the reconstruction algorithm.acq
is the optional entity for the set of acquisition parameters.dir
is the optional entity for the phase encoding direction (see here).
Note that one mandatory BIDs entity is missing: the ``sub`` entity, correspondent to the subject label. This is because it has to be specified while calling phys2bids
, as it’s explained in the tutorial section “generating-outputs-in-bids-format”. The session entity can be specified in the same way. Moreover, if you have a multifrequency file there will be another entity, recording
automatically added to those specified here, and containing the sample frequency of the different outputs.
Let’s try to read the first statement in the example:
“If the name of the file (``physinfo``) contains the string ``’*tutorial’
, then assign the entity ``task
with valuetest
, therun
as number00
, and the reconstruction used aslabchart
”*
Note that we used only a subset of possible entities.
Functional code¶
68 69 70 71 | # ############################## #
# ## Don't modify below this! ## #
# ############################## #
return info
|
This part is very simple: it returns the dictionary populated by the correct statement to the main program. It’s important not to modify this part of the file. Instead, you can copy and paste it into your own heuristic file.
Using the heuristic file¶
Once you modified your heuristic file or created a new one, you can save it anywhere you want, as a python script (somename.py
). Check that the file is executable! Then, you will have to call phys2bids
using the -heur
, the -sub
, and optionally the -ses
, arguments:
phys2bids -in tutorial_file.txt -indir /home/arthurdent/git/phys2bids/phys2bids/tests/data/ -chtrig 1 -ntp 158 -tr 1.2 -outdir /home/arthurdent/physio -heur /home/arthurdent/git/phys2bids/phys2bids/heuristics/heur_tutorial.py -sub 006 -ses 01
Remember to specify the full path to the heuristic file. A copy of the heuristic file will be saved in the site folder.
You can find more information in the relevant tutorial section.