Skip to content

Commit 5a9fb5d

Browse files
committed
Merge branch 'master' into dev
2 parents f724571 + d67445d commit 5a9fb5d

17 files changed

Lines changed: 124 additions & 42 deletions

.github/workflows/make_binaries.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
build:
1212
strategy:
1313
matrix:
14-
os: [macos-13, ubuntu-20.04, windows-latest] # not using latest based on https://github.com/Nuitka/Nuitka/issues/2240#issuecomment-1564030218
14+
os: [macos-15, ubuntu-24.04, windows-2025] # not using latest based on https://github.com/Nuitka/Nuitka/issues/2240#issuecomment-1564030218
1515

1616
runs-on: ${{ matrix.os }}
1717

.github/workflows/publish_doc.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
run: echo "::set-output name=dir::$(pip cache dir)"
3838

3939
- name: Cache dependencies
40-
uses: actions/cache@v2
40+
uses: actions/cache@v4
4141
with:
4242
path: ${{ steps.pip-cache.outputs.dir }}
4343
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements-doc.txt') }}

.github/workflows/tests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ jobs:
1010
matrix:
1111
# https://help.github.com/articles/virtual-environments-for-github-actions
1212
platform:
13-
- ubuntu-latest # ubuntu-22.04
14-
- macos-13 # macOS-13 -
15-
- windows-latest # windows-2022
16-
python-version: ["3.8", "3.9", "3.10", "3.11"]
13+
- ubuntu-24.04 # ubuntu-24.04
14+
- macos-15 # macOS-15
15+
- windows-2025 # windows-2025
16+
python-version: ["3.11", "3.12", "3.13", "3.14"]
1717

1818
steps:
1919
- uses: actions/checkout@v4

dcm2bids/acquisition.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ def dstSidecarData(self, idList):
284284
f"will be made "
285285
f"for json file '{self.dstFile}.json' "
286286
"with this id.")
287+
elif isinstance(val, str) and not val:
288+
data.pop(key, None)
287289
else:
288290
values.append(idList.get(val, val))
289291
if values[-1] != val:
@@ -308,9 +310,8 @@ def dstSidecarData(self, idList):
308310

309311
if len(flat_value_list) == 1:
310312
data[key] = flat_value_list[0]
311-
else:
313+
elif flat_value_list:
312314
data[key] = flat_value_list
313-
314315
return data
315316

316317
@staticmethod

dcm2bids/cli/dcm2bids.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,52 @@ def _build_arg_parser():
2626

2727
p.add_argument("-d", "--dicom_dir",
2828
required=True, nargs="+",
29-
help="DICOM directory(ies) or archive(s) (" +
30-
DEFAULT.arch_extensions + ").")
29+
help="Path to one or more directories or archives"
30+
f" ({DEFAULT.arch_extensions}) containing the DICOM files for a"
31+
" single participant and session to be converted to BIDS."
32+
)
3133

3234
p.add_argument("-p", "--participant",
3335
required=True,
34-
help="Participant ID.")
36+
help="Participant ID to be used in the BIDS dataset filenames"
37+
" (e.g. sub-<PARTICIPANT>)."
38+
)
3539

3640
p.add_argument("-s", "--session",
3741
required=False,
3842
default=DEFAULT.cli_session,
39-
help="Session ID. [%(default)s]")
43+
help="Session ID to be used in the BIDS dataset filenames"
44+
" (e.g. ses-<SESSION>). If not provided, no session"
45+
" entity will be added to the BIDS filenames."
46+
)
4047

4148
p.add_argument("-c", "--config",
4249
required=True,
43-
help="JSON configuration file (see example/config.json).")
50+
help="JSON configuration that specifies additional parameters for"
51+
" BIDS conversion. See the documentation for more information:"
52+
f" \nhttps://unfmontreal.github.io/Dcm2Bids/{__version__}/how-to/create-config-file/" # noqa: E501
53+
)
4454

4555
p.add_argument("-o", "--output_dir",
4656
required=False,
4757
default=DEFAULT.output_dir,
48-
help="Output BIDS directory. [%(default)s]")
58+
help="Output BIDS directory. Defaults to the current working directory."
59+
)
4960

5061
g = p.add_mutually_exclusive_group()
5162
g.add_argument("--auto_extract_entities",
5263
action='store_true',
5364
help="If set, it will automatically try to extract entity"
5465
"information [task, dir, echo] based on the suffix and datatype."
55-
" [%(default)s]")
66+
" Default is [%(default)s]")
5667

5768
g.add_argument("--do_not_reorder_entities",
5869
action='store_true',
5970
help="If set, it will not reorder entities according to the relative "
6071
"ordering indicated in the BIDS specification and use the "
6172
"order defined in custom_entities by the user.\n"
6273
"Cannot be used with --auto_extract_entities. "
63-
" [%(default)s]")
74+
" Default is [%(default)s]")
6475

6576
p.add_argument("--bids_validate",
6677
action='store_true',
@@ -87,7 +98,9 @@ def _build_arg_parser():
8798
required=False,
8899
default=DEFAULT.cli_log_level,
89100
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
90-
help="Set logging level to the console. [%(default)s]")
101+
help="Set logging level to the console."
102+
" The default level is [%(default)s]"
103+
)
91104

92105
p.add_argument("-v", "--version",
93106
action="version",

dcm2bids/cli/dcm2bids_helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
"""
44
Converts DICOM files to NIfTI files including their JSON sidecars in a
5-
temporary directory which can be inspected to make a dc2mbids config file.
5+
temporary directory which can be inspected to make a dcm2bids config file.
66
"""
77
import argparse
88
import logging

dcm2bids/sidecar.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ def compare(name, pattern):
297297
if not self.case_sensitive:
298298
name = name.lower()
299299
pattern = pattern.lower()
300-
301300
return fnmatch(name, pattern)
302301

303302
def compare_list(name, pattern):
@@ -396,10 +395,21 @@ def compare_float(name, pattern):
396395

397396
elif isinstance(name, list):
398397
result.append(compare_list(name, pattern))
398+
<<<<<<< HEAD
399399
elif name:
400400
result.append(compare(name, pattern))
401401
else:
402402
result.append(False)
403+
=======
404+
else:
405+
# If criteria is empty and key not found in json
406+
if not name and not pattern:
407+
result.append(True)
408+
elif name and pattern:
409+
result.append(compare(name, pattern))
410+
else:
411+
result.append(False)
412+
>>>>>>> master
403413

404414
return all(result)
405415

dcm2bids/utils/tools.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def check_github_latest(github_repo, timeout=3):
4949
"your machine is probably not connected to the Internet.")
5050
logger.debug(f"Reason {e.reason}")
5151
return "no_internet"
52+
except TimeoutError as e:
53+
logger.warning(f"Timeout")
54+
logger.debug(f"Socket timeout: {e}")
55+
return "no_internet"
5256
else:
5357
content = json.loads(response.read())
5458
return content["tag_name"]

dcm2bids/utils/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
from pathlib import Path
88
from subprocess import Popen, PIPE
99

10+
from dcm2bids.version import __version__
1011

1112
class DEFAULT(object):
1213
""" Default values of the package"""
1314

1415
doc = "Documentation at https://unfmontreal.github.io/Dcm2Bids/"
1516

1617
link_bids_validator = "https://github.com/bids-standard/bids-validator#quickstart"
17-
link_doc_intended_for = "https://unfmontreal.github.io/Dcm2Bids/docs/tutorial/first-steps/#populating-the-config-file"
18+
link_doc_intended_for = f"https://unfmontreal.github.io/Dcm2Bids/{__version__}/tutorial/first-steps/#populating-the-config-file" # noqa: E501
1819

1920
# cli dcm2bids
2021
cli_session = ""

docs/how-to/create-config-file.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
},
5757
"sidecar_changes": {
5858
"TaskName": "learning",
59-
"IntendedFor": "id_task_learning"
59+
"IntendedFor": "id_task_learning",
60+
""
6061
}
6162
}
6263
]
@@ -99,6 +100,20 @@ the value of `SeriesDescription` of a sidecar. `AXIAL_T2_SPACE` will be a match,
99100
prefer to also match with the filename of the sidecar. Note that filename are
100101
subject to change depending on the dcm2niix version in use.
101102

103+
In some cases, a user may want to select a criterion based on a key that must not exist
104+
in the list of sidecars[^1]. To validate that this key is absent, the user should provide
105+
an empty pattern.
106+
107+
Example:
108+
109+
```json
110+
{
111+
"criteria": {
112+
"EchoNumber": ""
113+
}
114+
}
115+
```
116+
102117
You can enter several criteria. **All criteria must match** for a description to
103118
be linked to a sidecar.
104119

@@ -156,20 +171,23 @@ custom_entities could also be combined with extractors. See
156171

157172
## sidecar_changes, id and IntendedFor
158173

159-
Optional field to change or add information in a sidecar.
174+
Optional field to change, delete or add information in a sidecar.
160175

161-
:warning: `IntendedFor` is now considered a sidecar_changes.
176+
:warning: `IntendedFor` is now considered a sidecar_changes and does support list.
162177

163178
Example:
164179

165180
```json
166181
{
167182
"sidecar_changes": {
183+
"AcquisitionDuration": "",
168184
"IntendedFor": "task_rest"
169185
}
170186
}
171187
```
172188

189+
If you want to delete a key in a sidecar you can set it to an empty string.
190+
173191
If you want to add an `IntendedFor` entry or any extra sidecar linked to a
174192
specific file, you will need to set an id to the corresponding description and
175193
put the same id with `IntendedFor`.

0 commit comments

Comments
 (0)