Skip to content

Commit

Permalink
Merge pull request #304 from UNFmontreal/allow_user_to_use_old_way_in…
Browse files Browse the repository at this point in the history
…tendedFor
  • Loading branch information
SamGuay authored Jul 17, 2024
2 parents e1bd13c + 5a00d3f commit 989b185
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 8 deletions.
15 changes: 12 additions & 3 deletions dcm2bids/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging
from os.path import join as opj
from os import sep

from dcm2bids.utils.utils import DEFAULT
from dcm2bids.version import __version__
Expand All @@ -30,6 +31,7 @@ def __init__(
id=None,
src_sidecar=None,
sidecar_changes=None,
bids_uri=None,
do_not_reorder_entities=None,
**kwargs
):
Expand All @@ -44,6 +46,7 @@ def __init__(
self.suffix = suffix
self.custom_entities = custom_entities
self.src_sidecar = src_sidecar
self.bids_uri = bids_uri
self.do_not_reorder_entities = do_not_reorder_entities

if sidecar_changes is None:
Expand Down Expand Up @@ -284,10 +287,16 @@ def dstSidecarData(self, idList):
else:
values.append(idList.get(val, val))
if values[-1] != val:
if isinstance(values[-1], list):
values[-1] = ["bids::" + img_dest for img_dest in values[-1]]
if self.bids_uri == DEFAULT.bids_uri:
if isinstance(values[-1], list):
values[-1] = ["bids::" + img_dest for img_dest in values[-1]]
else:
values[-1] = "bids::" + values[-1]
else:
values[-1] = "bids::" + values[-1]
if isinstance(values[-1], list):
values[-1] = [img_dest.replace(self.participant.name + sep, "") for img_dest in values[-1]]
else:
values[-1] = values[-1].replace(self.participant.name + sep, "")

# handle if nested list vs str
flat_value_list = []
Expand Down
3 changes: 2 additions & 1 deletion dcm2bids/dcm2bids_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def run(self):
self.config.get("search_method", DEFAULT.search_method),
self.config.get("case_sensitive", DEFAULT.case_sensitive),
self.config.get("dup_method", DEFAULT.dup_method),
self.config.get("post_op", DEFAULT.post_op)
self.config.get("post_op", DEFAULT.post_op),
self.config.get("bids_uri", DEFAULT.bids_uri)
)
parser.build_graph()
parser.build_acquisitions(self.participant)
Expand Down
32 changes: 29 additions & 3 deletions dcm2bids/sidecar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

from dcm2bids.acquisition import Acquisition
from dcm2bids.utils.io import load_json
from dcm2bids.utils.utils import DEFAULT, convert_dir, combine_dict_extractors, splitext_
from dcm2bids.utils.utils import (DEFAULT, convert_dir, combine_dict_extractors,
splitext_)

compare_float_keys = ["lt", "gt", "le", "ge", "btw", "btwe"]

Expand Down Expand Up @@ -100,11 +101,13 @@ def __init__(self,
search_method=DEFAULT.search_method,
case_sensitive=DEFAULT.case_sensitive,
dup_method=DEFAULT.dup_method,
post_op=DEFAULT.post_op):
post_op=DEFAULT.post_op,
bids_uri=DEFAULT.bids_uri):
self.logger = logging.getLogger(__name__)
self._search_method = ""
self._dup_method = ""
self._post_op = ""
self._bids_uri = ""
self.graph = OrderedDict()
self.acquisitions = []
self.extractors = extractors
Expand All @@ -116,6 +119,7 @@ def __init__(self,
self.case_sensitive = case_sensitive
self.dup_method = dup_method
self.post_op = post_op
self.bids_uri = bids_uri

@property
def search_method(self):
Expand Down Expand Up @@ -220,6 +224,25 @@ def post_op(self, value):
raise ValueError("post_op is not defined correctly. "
"Please check the documentation.")

@property
def bids_uri(self):
return self._bids_uri

@bids_uri.setter
def bids_uri(self, value):
"""
Checks if the method bids_uri is using is implemented
Warns the user if not and fall back to default
"""
if value in DEFAULT.bids_uri_choices:
self._bids_uri = value
else:
self.bids_uri = DEFAULT.bids_uri
self.logger.warning(
"BIDS URI methods implemented: %s", DEFAULT.bids_uri_choices)
self.logger.warning(f"{value} is not a bids URI method implemented.")
self.logger.warning(f"Falling back to default: {DEFAULT.bids_uri}.")

@property
def case_sensitive(self):
return self._case_sensitive
Expand Down Expand Up @@ -396,8 +419,10 @@ def build_acquisitions(self, participant):
desc = valid_descriptions[0]
desc, sidecar = self.searchDcmTagEntity(sidecar, desc)
acq = Acquisition(participant,
src_sidecar=sidecar,
bids_uri=self.bids_uri,
do_not_reorder_entities=self.do_not_reorder_entities,
src_sidecar=sidecar, **desc)
**desc)
acq.setDstFile()

if acq.id:
Expand All @@ -416,6 +441,7 @@ def build_acquisitions(self, participant):
self.logger.warning(f"Several Pairing <- {sidecarName}")
for desc in valid_descriptions:
acq = Acquisition(participant,
bids_uri=self.bids_uri,
do_not_reorder_entities=self.do_not_reorder_entities,
**desc)
self.logger.warning(f" -> {acq.suffix}")
Expand Down
2 changes: 2 additions & 0 deletions dcm2bids/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class DEFAULT(object):
dup_method = "run"
runTpl = "_run-{:02d}"
dupTpl = "_dup-{:02d}"
bids_uri_choices = ["URI", "relative"]
bids_uri = "URI"
case_sensitive = True

# Entity table:
Expand Down
34 changes: 34 additions & 0 deletions tests/data/config_test_multiple_intendedfor_uri_relative.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"search_method": "fnmatch",
"extractors": {"SeriesDescription": ["task-(?P<task>[a-zA-Z0-9]+)"]},
"bids_uri": "relative",
"descriptions": [
{
"id": "localizer",
"datatype": "localizer",
"suffix": "localizer",
"criteria": {
"SeriesDescription": "locali*"
}
},
{
"id": "T1",
"datatype": "anat",
"suffix": "T1w",
"criteria": {
"SidecarFilename": "*MPRAGE*"
}
},
{
"datatype": "fmap",
"suffix": "fmap",
"criteria": {
"EchoNumber": 1,
"EchoTime": 0.00492
},
"sidecar_changes": {
"IntendedFor": ["localizer", "T1"]
}
}
]
}
29 changes: 28 additions & 1 deletion tests/test_dcm2bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,4 +591,31 @@ def test_dcm2bids_no_reorder_entities():
func_json = os.path.join(bids_dir.name, "sub-01",
"func",
"sub-01_acq-highres_task-rest_bold.json")
assert os.path.exists(func_json)
assert os.path.exists(func_json)


def test_dcm2bids_multiple_intendedFor():
bids_dir = TemporaryDirectory()

tmp_sub_dir = os.path.join(bids_dir.name, DEFAULT.tmp_dir_name, "sub-01")
shutil.copytree(os.path.join(TEST_DATA_DIR, "sidecars"), tmp_sub_dir)

app = Dcm2BidsGen(TEST_DATA_DIR, "01",
os.path.join(TEST_DATA_DIR,
"config_test_multiple_intendedfor_uri_relative.json"),
bids_dir.name,
auto_extract_entities=True)
app.run()

epi_file = os.path.join(bids_dir.name, "sub-01", "fmap", "sub-01_fmap.json")
data = load_json(epi_file)

assert os.path.exists(epi_file)
assert data["IntendedFor"] == [os.path.join("localizer",
"sub-01_run-01_localizer.nii"),
os.path.join("localizer",
"sub-01_run-02_localizer.nii"),
os.path.join("localizer",
"sub-01_run-03_localizer.nii"),
os.path.join("anat",
"sub-01_T1w.nii")]

0 comments on commit 989b185

Please sign in to comment.