diff --git a/README.md b/README.md index a73744a8..4dc43897 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,16 @@ Your friendly DICOM converter. `dcm2bids` reorganises NIfTI files using [dcm2niix][dcm2niix-github] into the [Brain Imaging Data Structure][bids] (BIDS). + +## Major upgrade with dcm2bids >=3.0.0 + +⚠️ Breaking changes alert ⚠️ + +**dcm2bids>=3.0.0 is not compatible with config files made for v2.1.9 and below**. +In order to develop dcm2bids new features we had to rewrite some of its code. +Since v3.0.0, dcm2bids has become **more powerful** and **more flexible** while reducing the burden of creating config files. Porting your config file should be relatively easy by following the [How-to upgrade][dcm2bids-upgrade] page. +If you have any issues with it don't hesitate to report it on [Neurostars][neurostars-dcm2bids]. + ## Scope `dcm2bids` is a community-centered project. It aims to be a friendly, @@ -55,12 +65,13 @@ Before posting your question, you may want to first browse through questions tha [bids-examples]: https://github.com/bids-standard/bids-examples [bids-spec]: https://bids-specification.readthedocs.io/en/stable/ [dcm2bids-doc]: https://unfmontreal.github.io/Dcm2Bids -[dcm2bids-install]: https://unfmontreal.github.io/Dcm2Bids/docs/get-started/install/ -[dcm2bids-tutorial]: https://unfmontreal.github.io/Dcm2Bids/docs/tutorial/first-steps/#tutorial-first-steps -[dcm2bids-advanced]: https://unfmontreal.github.io/Dcm2Bids/docs/advanced/ +[dcm2bids-install]: https://unfmontreal.github.io/Dcm2Bids/latest/get-started/install/ +[dcm2bids-tutorial]: https://unfmontreal.github.io/Dcm2Bids/latest/tutorial/first-steps/#tutorial-first-steps +[dcm2bids-advanced]: https://unfmontreal.github.io/Dcm2Bids/latest/advanced/ +[dcm2bids-upgrade]: https://unfmontreal.github.io/Dcm2Bids/latest/upgrade/ [dcm2bids-issues]: https://github.com/UNFmontreal/Dcm2Bids/issues [dcm2niix-install]: https://github.com/rordenlab/dcm2niix#install [dcm2niix-github]: https://github.com/rordenlab/dcm2niix [neurostars]: https://neurostars.org/ [neurostars-dcm2bids]: https://neurostars.org/tag/dcm2bids -[dcm2bids-contributing]: https://unfmontreal.github.io/Dcm2Bids/CONTRIBUTING +[dcm2bids-contributing]: https://unfmontreal.github.io/Dcm2Bids/latest/how-to/contributing/ diff --git a/dcm2bids/cli/dcm2bids.py b/dcm2bids/cli/dcm2bids.py index 2efeaba8..49da35cb 100644 --- a/dcm2bids/cli/dcm2bids.py +++ b/dcm2bids/cli/dcm2bids.py @@ -49,7 +49,7 @@ def _build_arg_parser(): p.add_argument("--auto_extract_entities", action='store_true', help="If set, it will automatically try to extract entity" - "information [task, dir, echo] based on the suffix and dataType." + "information [task, dir, echo] based on the suffix and datatype." " [%(default)s]") p.add_argument("--bids_validate", diff --git a/dcm2bids/version.py b/dcm2bids/version.py index b2a69aa8..b1fc05de 100644 --- a/dcm2bids/version.py +++ b/dcm2bids/version.py @@ -4,7 +4,7 @@ _version_major = 3 _version_minor = 0 _version_micro = 0 -_version_extra = 'dev' +_version_extra = 'rc1' # Construct full version string from these. _ver = [_version_major, _version_minor] diff --git a/docs/changelog.md b/docs/changelog/index.md similarity index 100% rename from docs/changelog.md rename to docs/changelog/index.md diff --git a/docs/get-started/index.md b/docs/get-started/index.md index b510426c..18c0fcfb 100644 --- a/docs/get-started/index.md +++ b/docs/get-started/index.md @@ -37,5 +37,5 @@ function: [installation]: ./install.md [tutorial]: ../tutorial/first-steps.md [how-to]: ../how-to -[reference]: /reference/dcm2bids +[reference]: ../dcm2bids [get-help]: ../how-to/get-help.md diff --git a/docs/get-started/install.md b/docs/get-started/install.md index 0043f170..a11c3123 100644 --- a/docs/get-started/install.md +++ b/docs/get-started/install.md @@ -7,6 +7,76 @@ date: 2022-04-17 # Installation +There are several ways to install dcm2bids. + +## Installing binary executables + +From dcm2bids>=3.0.0, we provide binaries for macOS, Windows and Linux +(debian-based and rhel-based). + +They can easily been downloaded from +[the release page](https://github.com/UNFmontreal/Dcm2Bids/releases/latest). + +Once downloaded, you should be able to extract the `dcm2bids`, +`dcm2bids_scaffold`, and `dcm2bids_helper` files and use them with the full +path. + +=== "Example on Ubuntu 22.04" + + ```bash + sam:~/software$ curl -fLO https://github.com/unfmontreal/dcm2bids/releases/latest/download/dcm2bids_debian-based_3.0.rc1.tar.gz + sam:~/software$ tar -xvf dcm2bids_debian-based*.tar.gz + sam:~/software$ cd ../data + sam:~/data$ ~/software/dcm2bids_scaffold -o new-bids-project + ``` + +=== "Ouput" + + ```bash + sam:~/software$ curl -fLO https://github.com/unfmontreal/dcm2bids/releases/latest/download/dcm2bids_debian-based_3.0.0rc1.tar.gz + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 + 100 40.6M 100 40.6M 0 0 23.2M 0 0:00:01 0:00:01 --:--:-- 36.4M + + sam:~/software$ tar -xvf dcm2bids_debian-based*.tar.gz + dcm2bids + dcm2bids_helper + dcm2bids_scaffold + + sam:~/software$ cd ../data + + sam:~/data$ ~/software/dcm2bids_scaffold -o new-bids-project + INFO | --- dcm2bids_scaffold start --- + INFO | Running the following command: /home/sam/software/dcm2bids_scaffold -o new-bids-project + INFO | OS version: Linux-5.15.0-76-generic-x86_64-with-glibc2.31 + INFO | Python version: 3.10.12 | packaged by conda-forge | (main, Jun 23 2023, 22:40:32) [GCC 12.3.0] + INFO | dcm2bids version: 3.0.rc1 + INFO | Checking for software update + INFO | Currently using the latest version of dcm2bids. + INFO | The files used to create your BIDS directory were taken from https://github.com/bids-standard/bids-starter-kit. + + INFO | Tree representation of new-bids-project/ + INFO | new-bids-project/ + INFO | ├── code/ + INFO | ├── derivatives/ + INFO | ├── sourcedata/ + INFO | ├── tmp_dcm2bids/ + INFO | │ └── log/ + INFO | │ └── scaffold_20230716-122220.log + INFO | ├── .bidsignore + INFO | ├── CHANGES + INFO | ├── dataset_description + INFO | ├── participants.json + INFO | ├── participants.tsv + INFO | └── README + INFO | Log file saved at new-bids-project/tmp_dcm2bids/log/scaffold_20230716-122220.log + INFO | --- dcm2bids_scaffold end --- + ``` + +## Installing using pip or conda + Before you can use dcm2bids, you will need to get it installed. This page guides you through a minimal, typical dcm2bids installation workflow that is sufficient to complete all dcm2bids tasks. @@ -21,6 +91,8 @@ dcm2bids. ??? tip "You just want the installation command?" + You can use the binaries provided with each release (starting with dcm2bids>=3) + If you are used to installing packages, you can get it from PyPI or conda: `pip install dcm2bids` @@ -134,8 +206,9 @@ installed and correctly setup on your computer as it is the easiest way to install dcm2bids and its dependencies on any OS. We assume that if you want to install it in a different way, you have enough skills to do it on your own. -If you installed Anaconda and want to use the graphical user interface (GUI), you can follow the steps as -demonstrated below and only read the steps until the end of the installation guide. +If you installed Anaconda and want to use the graphical user interface (GUI), +you can follow the steps as demonstrated below and only read the steps until the +end of the installation guide. ??? info "Create your environment with the **Anaconda Navigator** GUI" @@ -168,8 +241,6 @@ But this would install the software in the main environment instead of a dedicated one, assuming none were active. This could have atrocious dependencies issues in the long-term if you want to install other software. - - #### Create environment.yml That is exactly why dedicated environments were invented. To help creating diff --git a/docs/how-to/create-config-file.md b/docs/how-to/create-config-file.md index 005e9899..5a11fcb3 100644 --- a/docs/how-to/create-config-file.md +++ b/docs/how-to/create-config-file.md @@ -6,53 +6,57 @@ { "descriptions": [ { - "dataType": "anat", - "modalityLabel": "T2w", + "datatype": "anat", + "suffix": "T2w", "criteria": { "SeriesDescription": "*T2*", "EchoTime": 0.1 }, - "sidecarChanges": { + "sidecar_changes": { "ProtocolName": "T2" } }, { - "dataType": "func", - "modalityLabel": "bold", - "customLabels": "task-rest", + "id": "task-rest", + "datatype": "func", + "suffix": "bold", + "custom_entities": "task-rest", "criteria": { "ProtocolName": "func_task-*", "ImageType": ["ORIG*", "PRIMARY", "M", "MB", "ND", "MOSAIC"] } }, { - "dataType": "fmap", - "modalityLabel": "fmap", - "intendedFor": 1, + "datatype": "fmap", + "suffix": "fmap", "criteria": { "ProtocolName": "*field_mapping*" + }, + "sidecar_changes": { + "IntendedFor": "task_rest" } }, { - "dataType": "func", - "modalityLabel": "bold", - "customLabels": "task-learning", + "id": "id_task_learning", + "datatype": "func", + "suffix": "bold", + "custom_entities": "task-learning", "criteria": { "SeriesDescription": "bold_task-learning" }, - "sidecarChanges": { + "sidecar_changes": { "TaskName": "learning" } }, { - "dataType": "fmap", - "modalityLabel": "epi", + "datatype": "fmap", + "suffix": "epi", "criteria": { "SeriesDescription": "fmap_task-learning" }, - "IntendedFor": 2, - "sidecarChanges": { - "TaskName": "learning" + "sidecar_changes": { + "TaskName": "learning", + "IntendedFor": "id_task_learning" } } ] @@ -98,7 +102,7 @@ subject to change depending on the dcm2niix version in use. You can enter several criteria. **All criteria must match** for a description to be linked to a sidecar. -## dataType +## datatype It is a mandatory field. Here is a definition from `bids v1.2.0` : @@ -108,12 +112,12 @@ It is a mandatory field. Here is a definition from `bids v1.2.0` : > field maps), anat (structural imaging such as T1, T2, etc.), meg > (magnetoencephalography), beh (behavioral). -## modalityLabel +## suffix It is a mandatory field. It describes the modality of the acquisition like `T1w`, `T2w` or `dwi`, `bold`. -## customLabels +## custom_entities It is an optional field. For some acquisitions, you need to add information in the file name. For resting state fMRI, it is usually `task-rest`. @@ -124,19 +128,52 @@ specifications][bids-spec]. For a longer example of a Dcm2Bids config json, see [here](https://github.com/unfmontreal/Dcm2Bids/blob/master/example/config.json). -## sidecarChanges +Note that the different bids labels must come in a very specific order to be +bids valid filenames. If the custom_entities fields that are entered that are in +the wrong order, then dcm2bids will reorder them for you. + +For example if you entered: + +```json +"custom_entities": "run-01_task-rest" +``` + +when running dcm2bids, you will get the following warning: + +```bash +WARNING:dcm2bids.structure:✅ Filename was reordered according to BIDS entity table order: + from: sub-ID01_run-01_task-rest_bold + to: sub-ID01_task-rest_run-01_bold +``` + +custom_entities could also be combined with extractors. See +[custom_entities combined with extractors](./use-advanced-commands.md#custom_entities-combined-with-extractors) + +## sidecar_changes, id and IntendedFor Optional field to change or add information in a sidecar. -## intendedFor +:warning: `IntendedFor` is now considered a sidecar_changes. + +Example: + +```json +{ + "sidecar_changes": { + "IntendedFor": "task_rest" + } +} +``` + +If you want to add an `IntendedFor` entry or any extra sidecar linked to a +specific file, you will need to set an id to the corresponding description and +put the same id with `IntendedFor`. -Optional field to add an `IntendedFor` entry in the sidecar of a fieldmap. Just -put the index or a list of indices of the description(s) that's intended for. +Fo example, **`task_rest`** means it is intended for `task-rest_bold` and +**`id_task_learning`** is intended for `task-learning_bold`. -Python index begins at `0` so in the example, **`1`** means it is intended for -`task-rest_bold` and **`2`** is intended for `task-learning` which will be -renamed to only `learning` because of the -`"sidecarChanges": { "TaskName": "learning" }` field. +You could also use this feature to feed sidecar such as `Source`` for example or +anything that suits your needs. ## Multiple config files diff --git a/docs/how-to/index.md b/docs/how-to/index.md index 1d6bb887..1c8e215a 100644 --- a/docs/how-to/index.md +++ b/docs/how-to/index.md @@ -18,4 +18,4 @@ title: How-to guides ## Development and Community -- [Contribute to dcm2bids](/CONTRIBUTING.md) +- [Contribute to dcm2bids](./contributing.md) diff --git a/docs/how-to/use-advanced-commands.md b/docs/how-to/use-advanced-commands.md index a8185c83..244718a9 100644 --- a/docs/how-to/use-advanced-commands.md +++ b/docs/how-to/use-advanced-commands.md @@ -1,47 +1,134 @@ -# How to use advanced commands and configuration +# How to use advanced configuration -These optional configurations could be insert in the configuration file at the -same level as the `"descriptions"` entry. +These optional configurations can be inserted in the configuration file at the +same level as the `"description"` entry. -``` +```json { - "searchMethod": "fnmatch", - "caseSensitive": true, - "defaceTpl": ["pydeface", "--outfile", "dstFile", "srcFile"], - "description": [ - ... + "extractors": { + "SeriesDescription": [ + "run-(?P[0-9]+)", + "task-(?P[0-9]+)" + ], + "BodyPartExamined": [ + "(?P[a-zA-Z]+)" ] + }, + "search_method": "fnmatch", + "case_sensitive": true, + "dup_method": "dup", + "post_op": [ + { + "cmd": "pydeface --outfile dst_file src_file", + "datatype": "anat", + "suffix": [ + "T1w", + "MP2RAGE" + ] + } + ], + "descriptions": [ + { + "datatype": "anat", + "suffix": "T2w", + "custom_entities": [ + "acq-highres", + "bodypart", + "run", + "task" + ], + "criteria": ... + } + ] } ``` -## searchMethod +## custom_entities combined with extractors + +default: None + +extractors will allow you to extract information embeded into sidecar files. In +the example above, it will try to match 2 different regex expressions (keys: +task, run) within the SeriesDescription field and bodypart in BodyPartExamined +field. + +By using the same keys in custom_entities and if found, it will add this new +entities directly into the final filename. custom_entities can be a list that +combined extractor keys and regular entities. If key is `task` it will +automatically add the field "TaskName" inside the sidecase file. + +## search_method -default: `"searchMethod": "fnmatch"` +default: `"search_method": "fnmatch"` fnmatch is the behaviour (See criteria) by default and the fall back if this option is set incorrectly. `re` is the other choice if you want more flexibility to match criteria. -## caseSensitive +## dup_method + +default: `"dup_method": "run"` + +run is the default behavior and will add '\_run-' to the customEntities of the +acquisition if it finds duplicate destination roots. + +dup will keep the last duplicate description and put `_dup-`to the +customEntities of the other acquisitions. This behavior is a +[heudiconv](https://heudiconv.readthedocs.io/en/latest/changes.html) inspired +feature. + +## case_sensitive -default: `"caseSensitive": "true"` +default: `"case_sensitive": "true"` If false, comparisons between strings/lists will be not case sensitive. It's -only disabled when used with `"searchMethod": "fnmatch"`. +only disabled when used with `"search_method": "fnmatch"`. -## defaceTpl +## post_op -default: `"defaceTpl": None` +default: `"post_op": []` -!!! danger The anonymizer option no longer exists from `v2.0.0`. It is still -possible to deface the anatomical nifti images. +post_op key allows you to run any post-processing analyses just before moving +the images to there respective directories. -For example, if you use the last version of pydeface, add: +For example, if you want to deface your T1w images you could use pydeface by +adding: -`"defaceTpl": "pydeface --outfile {dstFile} {srcFile}"` +```json +"post_op": [ + { + "cmd": "pydeface --outfile dst_file src_file", + "datatype": "anat", + "suffix": [ + "T1w", + "MP2RAGE" + ] + } +], +``` + +It will specifically run the corresponding `cmd` to any image that follow the +combinations datatype/suffix: `(anat, T1w) or (anat, MP2RAGE)`. -It is a template string and dcm2bids will replace {srcFile} and {dstFile} by the -source file (input) and the destination file (output). +!!! warning "Multiple post_op commands" + + Although you can add multiple commands, the combination datatype/suffix on which you want to run the command has to be unique. + You cannot run multiple commands on a specific combination datatype/suffix. + +```json +"post_op": [{"cmd": "pydeface --outfile dst_file src_file", + "datatype": "anat", + "suffix": ["T1w", "MP2RAGE"]}, + {"cmd": "my_new_script --input src_file --output dst_file ", + "datatype": "fmap", + "suffix": ["any"]}], +``` + +In this example the second command `my_new_script` will be running on any image +which datatype is fmap. + +Finally, this is a template string and dcm2bids will replace `src_file` and +`dst_file` by the source file (input) and the destination file (output). ## dcm2niixOptions @@ -56,3 +143,176 @@ default: `"compKeys": ["SeriesNumber", "AcquisitionTime", "SidecarFilename"]` Acquisitions are sorted using the sidecar data. The default behaviour is to sort by `SeriesNumber` then by `AcquisitionTime` then by the `SidecarFilename`. You can change this behaviour setting this key inside the configuration file. + +## criteria + +### Handle multi site filtering + +As mentionned in the [first-steps tutorial](../tutorial/first-steps.md), +criteria is the way to filter specific acquisitions. If you work with dicoms +from multiple sites you will need different criterias for the same kind of +acquisition. In order to reduce the length of the config file, we developped a +feature where for a specific criteria you can get multiple descriptions. + +```json +"criteria": { + "SeriesDescription": {"any" : ["*MPRAGE*", "*T1w*"]} +} +``` + +### Enhanced float/int comparison + +Criteria can help you filter acquisitions by comparing float/int sidecar. + +```json +"criteria": { + "RepetitionTime": { + "le": "0.0086" + } +} +``` + +In this example, dcm2bids will check if RepetitionTime is lower or equal to +0.0086. + +Here are the key coded to help you compare float/int sidecar. + +| key | operator | +| :--------: | :----------------------: | +| **`lt`** | lower than | +| **`le`** | lower than or equal to | +| **`gt`** | greater than | +| **`ge`** | greater than or equal to | +| **`btw`** | between | +| **`btwe`** | between or equal to | + +If you want to use btw or btwe you will need to give an ordered list like this. + +```json +"criteria": { + "EchoTime": { + "btwe": ["0.0029", "0.003"] + } +} +``` + +# How to use advanced commands + +## dcm2bids advanced options + +By now, you should be used to getting the `--help` information before running a +command. + +=== "Command" + + ```sh + dcm2bids --help + ``` + +=== "Output" + + ```sh hl_lines="2-3" + (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ dcm2bids --help + usage: dcm2bids [-h] -d DICOM_DIR [DICOM_DIR ...] -p PARTICIPANT [-s SESSION] -c CONFIG [-o OUTPUT_DIR] + [--auto_extract_entities] [--bids_validate] [--forceDcm2niix] [--clobber] + [-l {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-a] + + Reorganising NIfTI files from dcm2niix into the Brain Imaging Data Structure + dcm2bids 3.0.0 + + options: + -h, --help show this help message and exit + -d DICOM_DIR [DICOM_DIR ...], --dicom_dir DICOM_DIR [DICOM_DIR ...] + DICOM directory(ies) + -p PARTICIPANT, --participant PARTICIPANT + Participant ID + -s SESSION, --session SESSION + Session ID + -c CONFIG, --config CONFIG + JSON configuration file (see example/config.json) + -o OUTPUT_DIR, --output_dir OUTPUT_DIR + Output BIDS directory, Default: current directory (/home/sam/dcm2bids-tutorial/bids_project) + --auto_extract_entities If set, it will automatically try to extract entity information [task, dir, echo] + depending on the suffix and datatype. [False] + --bids_validate If set, once your conversion is done it will check if your output folder is BIDS valid. [False] + bids-validator needs to be installed check: https://github.com/bids-standard/bids-validator#quickstart + --forceDcm2niix Overwrite previous temporary dcm2niix output if it exists + --clobber Overwrite output if it exists + -l {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log_level {DEBUG,INFO,WARNING,ERROR,CRITICAL} + Set logging level + + Documentation at https://github.com/unfmontreal/Dcm2Bids + + ``` + +## --auto_extract_entities + +This option will automatically try to find 3 entities (task, dir and echo) for +specific datatype/suffix. + +- `task` in the SeriesDescription field + + Regular expression `task-(?P[a-zA-Z0-9]+)` + +- `dir` in the PhaseEncodedDirection field + + Regular expression `(?P-?j|i)` + +- `echo` in the EchoNumber field + + Regular expression `(?P[0-9])` + +If found, it will try to feed the filename with this entity **if they are +mandatory**. + +For example, a "pepolar" fieldmap data requires the entity `dir` (See +[BIDS specification](https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/01-magnetic-resonance-imaging-data.html#case-4-multiple-phase-encoded-directions-pepolar)). +If you set this parameter, it will automatically try to find this entity and add +it to the filename. + +So far and accordingly to the BIDS specification 5 datatype/suffix automatically +look for this 3 entities. + +| datatype | suffix | Entities | +| :------: | :----: | :------: | +| anat | MEGRE | echo | +| anat | MESE | echo | +| func | cbv | task | +| func | bold | task | +| func | sbref | task | +| fmap | epi | dir | + +Using the `--auto_extract_entitie`, if you want another combination of +datatype/suffix to be able to extract one or more of these 3 entities you need +to add the key of the entities needed using the field custom_entities like this +within your description: + +```json +"custom_entities": ["echo", "dir"] +``` + +:warning: If task is found, it will automatically add the field `TaskName` into +the sidecar file. It means you don't have to add the field in the config file +like this. + + + +```json +{ + "sidecar_changes": { + "TaskName": "learning" + } +} +``` + + + +:radioactive: You can find more detailed information by looking at the file [`dcm2bids/utils/utils.py`](../dcm2bids/utils/utils/) and +more specifically *`auto_extractors`* and *`auto_entities`* variables. + +## --bids_validate + +By default, dcm2bids will not validate your final BIDS structure. If needed, you +can install +[bids-validator](https://github.com/bids-standard/bids-validator#quickstart) and +activate this option. diff --git a/docs/tutorial/first-steps.md b/docs/tutorial/first-steps.md index 465abbf3..b44cd610 100644 --- a/docs/tutorial/first-steps.md +++ b/docs/tutorial/first-steps.md @@ -48,7 +48,8 @@ Note that you use `dcm2bids` as the name of the environment but you should use the name you gave your environment when you created it. If you used Anaconda Navigator to install dcm2bids and create you environment, -make sure to open your environment from Navigator as indicated in [Create your environment with the Anaconda Navigator GUI](../get-started/install.md#install-dcm2bids). +make sure to open your environment from Navigator as indicated in +[Create your environment with the Anaconda Navigator GUI](../get-started/install.md#install-dcm2bids). === "Command" @@ -79,7 +80,8 @@ You can test it with any command but a safe way is to use the `--help` command. ```sh (dcm2bids) sam:~$ dcm2bids --help usage: dcm2bids [-h] -d DICOM_DIR [DICOM_DIR ...] -p PARTICIPANT [-s SESSION] -c - CONFIG [-o OUTPUT_DIR] [--forceDcm2niix] [--clobber] + CONFIG [-o OUTPUT_DIR][--auto_extract_entities] [--bids_validate] + [--forceDcm2niix] [--clobber] [-l {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-a] Reorganising NIfTI files from dcm2niix into the Brain Imaging Data Structure @@ -98,6 +100,10 @@ You can test it with any command but a safe way is to use the `--help` command. -o OUTPUT_DIR, --output_dir OUTPUT_DIR Output BIDS directory, Default: current directory (/home/sam) + --auto_extract_entities + If set, it will automatically try to extract entityinformation [task, dir, echo] based on the suffix and datatype. [False] + --bids_validate If set, once your conversion is done it will check if your output folder is BIDS valid. [False] + bids-validator needs to be installed check: https://github.com/bids-standard/bids-validator#quickstart --forceDcm2niix Overwrite previous temporary dcm2niix output if it exists --clobber Overwrite output if it exists -l {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log_level {DEBUG,INFO,WARNING,ERROR,CRITICAL} @@ -118,7 +124,7 @@ You can test it with any command but a safe way is to use the `--help` command. ### Create a new directory for this tutorial -For the tutorial, you recommend that you create a new directory (folder) instead +For the tutorial, we recommend that you create a new directory (folder) instead of jumping straight into a real project directory with real data. In this tutorial, we decided to named our project directory `dcm2bids-tutorial`. @@ -159,6 +165,7 @@ scaffold_directory/ ├── participants.json ├── participants.tsv ├── README +├── .bidsignore └── sourcedata/ 3 directories, 5 files @@ -187,6 +194,8 @@ option. Create basic BIDS files and directories + Based on the material provided by + https://github.com/bids-standard/bids-starter-kit options: -h, --help show this help message and exit @@ -223,20 +232,69 @@ scaffold beforehand, the command will create it for you. ```sh (dcm2bids) sam:~/dcm2bids-tutorial$ dcm2bids_scaffold - (dcm2bids) sam:~/dcm2bids-tutorial$ ls - CHANGES dataset_description.json participants.json README - code derivatives participants.tsv sourcedata + INFO | --- dcm2bids_scaffold start --- + INFO | Running the following command: /home/sam/miniconda3/envs/dcm2bids-env/bin/dcm2bids_scaffold + INFO | OS version: Linux-5.19.0-45-generic-x86_64-with-glibc2.35 + INFO | Python version: 3.10.4 (main, May 29 2023, 11:10:38) [GCC 11.3.0] + INFO | dcm2bids version: 3.0.0 + INFO | Checking for software update + INFO | Currently using the latest version of dcm2bids. + INFO | The files used to create your BIDS directory were taken from https://github.com/bids-standard/bids-starter-kit. + + INFO | Tree representation of /home/sam/dcm2bids-tutorials/ + INFO | /home/sam/dcm2bids-tutorials/ + INFO | ├── code/ + INFO | ├── derivatives/ + INFO | ├── sourcedata/ + INFO | ├── tmp_dcm2bids/ + INFO | │ └── log/ + INFO | │ └── scaffold_20230703-163905.log + INFO | ├── .bidsignore + INFO | ├── CHANGES + INFO | ├── dataset_description + INFO | ├── participants.json + INFO | ├── participants.tsv + INFO | └── README + INFO | Log file saved at /home/sam/dcm2bids-tutorials/tmp_dcm2bids/log/scaffold_20230703-163905.log + INFO | --- dcm2bids_scaffold end --- + + (dcm2bids) sam:~/dcm2bids-tutorial$ ls -a + .bidsignore CHANGES dataset_description.json participants.json README + code derivatives participants.tsv sourcedata ``` **VS** ```sh (dcm2bids) sam:~/dcm2bids-tutorial$ dcm2bids_scaffold -o bids_project - (dcm2bids) sam:~/dcm2bids-tutorial$ ls -F - bids_project/ - (dcm2bids) sam:~/dcm2bids-tutorial$ ls -F bids_project/ - CHANGES dataset_description.json participants.json README - code/ derivatives/ participants.tsv sourcedata/ + INFO | --- dcm2bids_scaffold start --- + INFO | Running the following command: /home/sam/miniconda3/envs/dcm2bids-env/bin/dcm2bids_scaffold -o bids_project + INFO | OS version: Linux-5.19.0-45-generic-x86_64-with-glibc2.35 + INFO | Python version: 3.10.4 (main, May 29 2023, 11:10:38) [GCC 11.3.0] + INFO | dcm2bids version: 3.0.dev + INFO | Checking for software update + INFO | Currently using the latest version of dcm2bids. + INFO | The files used to create your BIDS directory were taken from https://github.com/bids-standard/bids-starter-kit. + + INFO | Tree representation of bids_project/ + INFO | bids_project/ + INFO | ├── code/ + INFO | ├── derivatives/ + INFO | ├── sourcedata/ + INFO | ├── tmp_dcm2bids/ + INFO | │ └── log/ + INFO | │ └── scaffold_20230703-205902.log + INFO | ├── .bidsignore + INFO | ├── CHANGES + INFO | ├── dataset_description + INFO | ├── participants.json + INFO | ├── participants.tsv + INFO | └── README + INFO | Log file saved at bids_project/tmp_dcm2bids/log/scaffold_20230703-205902.log + INFO | --- dcm2bids_scaffold end --- + (dcm2bids) sam:~/dcm2bids-tutorial$ ls -Fa bids_project + .bidsignore CHANGES dataset_description.json participants.json README + code derivatives participants.tsv sourcedata ``` For the purpose of the tutorial, you chose to specify the output directory @@ -433,6 +491,15 @@ As usual the first command will be to request the help info. DICOM files directory -o OUTPUT_DIR, --output_dir OUTPUT_DIR Output BIDS directory, Default: current directory + -n [NEST], --nest [NEST] + Nest a directory in . Useful if many helper runs are needed + to make a config file due to slight variations in MRI acquisitions. + Defaults to DICOM_DIR if no name is provided. + (Default: [False]) + --force, --force_dcm2niix + Force command to overwrite existing output files. + -l {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log_level {DEBUG,INFO,WARNING,ERROR,CRITICAL} + Set logging level to the console. [INFO] Documentation at https://github.com/unfmontreal/Dcm2Bids ``` @@ -449,7 +516,7 @@ the command, the current directory. one session of one participant only by targeting their directory, otherwise you may be overwhelmed by the number of files for nothing. - In this tutorial, there are two folders with data, one with data coming from a + In this tutorial, there are two directories with data, one with data coming from a Siemens scanner (`20180918Si`), and one with data coming from GE (20180918GE). The tutorial will use the data acquired on both scanners and Siemens scanner located in `sourcedata/dcm_qa_nih/In/` and pretend it is one participant only. @@ -463,9 +530,22 @@ the command, the current directory. === "Output" ```sh hl_lines="4" - (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ dcm2bids_helper -d sourcedata/dcm_qa_nih/In/ - Example in: - /home/sam/dcm2bids-tutorial/bids_project/tmp_dcm2bids/helper + INFO | --- dcm2bids_helper start --- + INFO | Running the following command: /home/sam/miniconda3/envs/dcm2bids-env/bin/dcm2bids_helper -d sourcedata/dcm_qa_nih/In/ + INFO | OS version: Linux-5.19.0-45-generic-x86_64-with-glibc2.35 + INFO | Python version: 3.10.4 (main, May 29 2023, 11:10:38) [GCC 11.3.0] + INFO | dcm2bids version: 3.0.0 + INFO | dcm2niix version: v1.0.20230411 + INFO | Checking for software update + INFO | Currently using the latest version of dcm2bids. + INFO | Currently using the latest version of dcm2niix. + INFO | Running: dcm2niix -b y -ba y -z y -f %3s_%f_%p_%t -o /home/sam/miniconda3/envs/dcm2bids-env/bin/dcm2bids_helper sourcedata/dcm_qa_nih/In/ + INFO | Check log file for dcm2niix output + + INFO | Helper files in: /home/sam/dcm2bids-tutorial/bids_project/tmp_dcm2bids/helper + + INFO | Log file saved at /home/sam/dcm2bids-tutorial/bids_project/tmp_dcm2bids/log/helper_20230703-210946.log + INFO | --- dcm2bids_helper end --- ``` ### Finding what you need in **tmp_dcm2bids/helper** @@ -801,12 +881,12 @@ task name: { "descriptions": [ { - "dataType": "func", - "modalityLabel": "bold", - "customLabels": "task-rest", + "datatype": "func", + "suffix": "bold", + "custom_entities": "task-rest", "criteria": { "SeriesDescription": "Axial EPI-FMRI (Interleaved I to S)*" - "sidecarChanges": { + "sidecar_changes": { "TaskName": "rest" } } @@ -829,13 +909,13 @@ task name: { "descriptions": [ { - "dataType": "func", - "modalityLabel": "bold", - "customLabels": "task-rest", + "datatype": "func", + "suffix": "bold", + "custom_entities": "task-rest", "criteria": { "SeriesDescription": "*Axial EPI-FMRI (Interleaved I to S)*" }, - "sidecarChanges": { + "sidecar_changes": { "TaskName": "rest" } } @@ -850,11 +930,11 @@ task name: the [release notes of version 17-March-2021 (v1.0.20210317)][dcm2niix-release] of dcmniix to now more, especially the [GE file naming behavior changes (%p protocol name and %d description) section](https://github.com/rordenlab/dcm2niix/issues/476). -Moving to the two fieldmaps, if you inspect their sidecar files (the same ones -that were compared in the +Moving to the fieldmaps, if you inspect their sidecar files (the same ones that +were compared in the [dcm2bids_helper section](#finding-what-you-need-in-tmpdcm2bidshelper)), you can -see a pattern of `"EPI PE=AP"` or `"EPI PE=PA"` in the `SeriesDescription` once -again. Is it enough to match only the correct acquisition? +see a pattern of `"EPI PE=AP"`, `"EPI PE=PA"`, `"EPI PE=RL"` and `"EPI PE=LR"` +in the `SeriesDescription` once again. You can test it, of course! @@ -863,6 +943,8 @@ You can test it, of course! ```sh grep "EPI PE=AP" tmp_dcm2bids/helper/*.json grep "EPI PE=PA" tmp_dcm2bids/helper/*.json + grep "EPI PE=RL" tmp_dcm2bids/helper/*.json + grep "EPI PE=LR" tmp_dcm2bids/helper/*.json ``` === "Output" @@ -875,52 +957,78 @@ You can test it, of course! (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ grep "EPI PE=PA" tmp_dcm2bids/helper/*.json tmp_dcm2bids/helper/004_In_EPI_PE=PA_20180918121230.json: "SeriesDescription": "EPI PE=PA", tmp_dcm2bids/helper/004_In_EPI_PE=PA_20180918121230.json: "ProtocolName": "EPI PE=PA", + (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ grep "EPI PE=RL" tmp_dcm2bids/helper/*.json + tmp_dcm2bids/helper/005_In_EPI_PE=RL_20180918121230.json: "SeriesDescription": "EPI PE=RL", + tmp_dcm2bids/helper/005_In_EPI_PE=RL_20180918121230.json: "ProtocolName": "EPI PE=RL", + (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ grep "EPI PE=LR" tmp_dcm2bids/helper/*.json + tmp_dcm2bids/helper/006_In_EPI_PE=LR_20180918121230.json: "SeriesDescription": "EPI PE=LR", + tmp_dcm2bids/helper/006_In_EPI_PE=LR_20180918121230.json: "ProtocolName": "EPI PE=LR", ``` +Now, Dcm2bids new feature `--auto_extract_entities` will help you with this +specific situations. Following BIDS naming scheme fieldmaps need to be named +with a dir entity. If you take a look each json file you'll find in their +respective sidecar PhaseEncodedDirection a different direction + +=== "Command" + + ```sh + grep "PhaseEncodedDirection\"" tmp_dcm2bids/helper/*_In_EPI_PE=*.json + ``` + +=== "Output" + + There are four matches per pattern but they come from the same file, so it is okay. + ```sh + (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ grep "PhaseEncodedDirection\"" tmp_dcm2bids/helper/*_In_EPI_PE=*.json + tmp_dcm2bids/helper/003_In_EPI_PE=AP_20180918121230.json: "PhaseEncodingDirection": "j-", + tmp_dcm2bids/helper/004_In_EPI_PE=PA_20180918121230.json: "PhaseEncodingDirection": "j", + tmp_dcm2bids/helper/005_In_EPI_PE=RL_20180918121230.json: "PhaseEncodingDirection": "i", + tmp_dcm2bids/helper/006_In_EPI_PE=LR_20180918121230.json: "PhaseEncodingDirection": "i-", + ``` + +This entity will be different for each fieldmap so there's no need to be more +specific. + +Please check the different use cases for this feature + Once you are sure of you matching criteria, you can update your configuration file with the appropriate info. -```json hl_lines="21 30" +```json hl_lines="4 21-23" { "descriptions": [ { - "dataType": "func", - "modalityLabel": "bold", - "customLabels": "task-rest", + "id": "id_task-rest", + "datatype": "func", + "suffix": "bold", + "custom_entities": "task-rest", "criteria": { "SeriesDescription": "Axial EPI-FMRI (Interleaved I to S)*" }, - "sidecarChanges": { + "sidecar_changes": { "TaskName": "rest" } }, { - "dataType": "fmap", - "modalityLabel": "epi", - "customLabels": "dir-AP", - "criteria": { - "SeriesDescription": "EPI PE=AP*" - }, - "intendedFor": 0 - }, - { - "dataType": "fmap", - "modalityLabel": "epi", - "customLabels": "dir-PA", + "datatype": "fmap", + "suffix": "epi", "criteria": { - "SeriesDescription": "EPI PE=PA*" + "SeriesDescription": "EPI PE=*" }, - "intendedFor": 0 + "sidecar_changes": { + "intendedFor": ["id_task-rest"] + } } ] } ``` -For fieldmaps, you need to add an `"intendedFor"` field to show that these -fieldmaps should be used with your fMRI acquisition. Have a look at the -explanation of [intendedFor](/docs/3-configuration/#intendedfor) in the -documentation or in the [BIDS specification][bids-fmap]. +For fieldmaps, you need to add an `"intendedFor"` as well as `id` field to show +that these fieldmaps should be used with your fMRI acquisition. Have a look at +the explanation of [intendedFor](/docs/3-configuration/#id-and-intendedfor) in +the documentation or in the [BIDS specification][bids-fmap]. !!! tip "Use an online JSON validator" @@ -947,7 +1055,8 @@ command. ```sh hl_lines="2-3" (dcm2bids) sam:~/dcm2bids-tutorial/bids_project$ dcm2bids --help - usage: dcm2bids [-h] -d DICOM_DIR [DICOM_DIR ...] -p PARTICIPANT [-s SESSION] -c CONFIG [-o OUTPUT_DIR] [--forceDcm2niix] [--clobber] + usage: dcm2bids [-h] -d DICOM_DIR [DICOM_DIR ...] -p PARTICIPANT [-s SESSION] -c CONFIG [-o OUTPUT_DIR] + [--auto_extract_entities] [--bids_validate] [--forceDcm2niix] [--clobber] [-l {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [-a] Reorganising NIfTI files from dcm2niix into the Brain Imaging Data Structure @@ -965,6 +1074,11 @@ command. JSON configuration file (see example/config.json) -o OUTPUT_DIR, --output_dir OUTPUT_DIR Output BIDS directory, Default: current directory (/home/sam/dcm2bids-tutorial/bids_project) + --auto_extract_entities + If set, it will automatically try to extract entityinformation [task, dir, echo] based on the suffix and datatype. [False] + --bids_validate If set, once your conversion is done it will check if your output folder is BIDS valid. [False] + bids-validator needs to be installed check: https://github.com/bids-standard/bids-validator#quickstart + --forceDcm2niix Overwrite previous temporary dcm2niix output if it exists --clobber Overwrite output if it exists -l {DEBUG,INFO,WARNING,ERROR,CRITICAL}, --log_level {DEBUG,INFO,WARNING,ERROR,CRITICAL} @@ -979,50 +1093,65 @@ As you can see, to run the `dcm2bids` command, you have to specify at least 3 required options with their argument. ```sh -dcm2bids -d path/to/source/data -p subject_id -c path/to/config/file.json +dcm2bids -d path/to/source/data -p subID -c path/to/config/file.json --auto_extract_entities ``` `dcm2bids` will create a directory which will be named after the argument specified for `-p`, and put the _BIDSified_ data in it. -For the tutorial, pretend that the subject_id is simply `ID01`. +For the tutorial, pretend that the subID is simply `ID01`. Note that if you don't specify the `-o` option, your current directory will be populated with the `sub-