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/:

 1import fnmatch
 2
 3
 4def heur(physinfo, take=""):
 5    """
 6    Set of if .. elif statements to fill BIDS names.
 7
 8    It requires the user (you!) to adjust it accordingly!
 9    It needs an ``if`` or ``elif`` statement for each file that
10    needs to be processed.
11    The statement will test if the ``physinfo``:
12        - is similar to a string (first case), or
13        - exactly matches a string (second case).
14
15    Parameters
16    ----------
17    physinfo: str
18        Name of an input file that should be bidsified (See Notes)
19
20    Returns
21    -------
22    info: dictionary of str
23        Dictionary containing BIDS keys
24
25    Notes
26    -----
27    The `if ..` structure should always be similar to
28    ```
29    if physinfo == 'somepattern':
30        info['var'] = 'somethingelse'
31    ```
32    or, in case it's a partial match
33    ```
34    if fnmatch.fnmatchcase(physinfo, '*somepattern?'):
35        info['var'] = 'somethingelse'
36    ```
37    Where:
38        - `physinfo` and `info` are dedicated keywords,
39        - 'somepattern' is the name of the file,
40        - 'var' is a bids key in the list below
41        - 'somethingelse' is the value of the key
42    """
43    info = {}
44    # ################################# #
45    # ##        Modify here!         ## #
46    # ##                             ## #
47    # ##  Possible variables are:    ## #
48    # ##    -info['task'] (required) ## #
49    # ##    -info['run']             ## #
50    # ##    -info['rec']             ## #
51    # ##    -info['acq']             ## #
52    # ##    -info['dir']             ## #
53    # ##                             ## #
54    # ##  Remember that they are     ## #
55    # ##  dictionary keys            ## #
56    # ##  See example below          ## #
57    # ################################# #
58
59    if fnmatch.fnmatchcase(physinfo, "*tutorial*"):
60        info["task"] = "test"
61        info["run"] = "01"
62        info["rec"] = "labchart"
63    elif physinfo == "Example":
64        info["task"] = "rest"
65        info["run"] = "01"
66        info["acq"] = "resp"
67
68    # ############################## #
69    # ## Don't modify below this! ## #
70    # ############################## #
71    return info

We can split this file into three parts: the initialisation, the dictionaries, and the functional code.

Initialisation

 1import fnmatch
 2
 3
 4def heur(physinfo, take=""):
 5    """
 6    Set of if .. elif statements to fill BIDS names.
 7
 8    It requires the user (you!) to adjust it accordingly!
 9    It needs an ``if`` or ``elif`` statement for each file that
10    needs to be processed.
11    The statement will test if the ``physinfo``:
12        - is similar to a string (first case), or
13        - exactly matches a string (second case).
14
15    Parameters
16    ----------
17    physinfo: str
18        Name of an input file that should be bidsified (See Notes)
19
20    Returns
21    -------
22    info: dictionary of str
23        Dictionary containing BIDS keys
24
25    Notes
26    -----
27    The `if ..` structure should always be similar to
28    ```
29    if physinfo == 'somepattern':
30        info['var'] = 'somethingelse'
31    ```
32    or, in case it's a partial match
33    ```
34    if fnmatch.fnmatchcase(physinfo, '*somepattern?'):
35        info['var'] = 'somethingelse'
36    ```
37    Where:
38        - `physinfo` and `info` are dedicated keywords,
39        - 'somepattern' is the name of the file,
40        - 'var' is a bids key in the list below
41        - 'somethingelse' is the value of the key
42    """
43    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 <https://www.w3schools.com/python/python_dictionaries.asp>``_ 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# ##        Modify here!         ## #
46# ##                             ## #
47# ##  Possible variables are:    ## #
48# ##    -info['task'] (required) ## #
49# ##    -info['run']             ## #
50# ##    -info['rec']             ## #
51# ##    -info['acq']             ## #
52# ##    -info['dir']             ## #
53# ##                             ## #
54# ##  Remember that they are     ## #
55# ##  dictionary keys            ## #
56# ##  See example below          ## #
57# ################################# #
58
59if fnmatch.fnmatchcase(physinfo, "*tutorial*"):
60    info["task"] = "test"
61    info["run"] = "01"
62    info["rec"] = "labchart"
63elif physinfo == "Example":
64    info["task"] = "rest"
65    info["run"] = "01"
66    info["acq"] = "resp"
67
This is the core of the function, and the part that should be adapted to process your files. In practice, it’s a if .. elif .. else statement..
You need an 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'
The list of possible keys is in the comment above, and corresponds to the list of possible entities of the BIDs specification:
  • 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 value test, the run as number 00, and the reconstruction used as labchart”*

Note that we used only a subset of possible entities.

Functional code

68# ############################## #
69# ## Don't modify below this! ## #
70# ############################## #
71return 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.