Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to retrieve json sidecar based on entities of nifti (after replacing extension) #1072

Open
psadil opened this issue Jul 19, 2024 · 1 comment

Comments

@psadil
Copy link

psadil commented Jul 19, 2024

I'm not entirely sure that this is expected to work, but it was a bit surprising to me. One of the entities associated with the fmap nifti is "fmap": "epi". But getting files with that entity excludes the associated json sidecar. I expected the json sidecar to have the same entities as the nifti, but for the extension.

import tempfile
from pathlib import Path
import nibabel as nb
import numpy as np
import json

import bids

sub = "0"

description = {"BIDSVersion": "1.9.0", "Name": "test"}

with tempfile.TemporaryDirectory() as d:
    bidsdir = Path(d)
    (bidsdir / "dataset_description.json").write_text(json.dumps(description))
    fmapdir = bidsdir / f"sub-{sub}" / "fmap"
    fmapdir.mkdir(parents=True)
    for direction in ["AP", "PA"]:
        img = fmapdir / f"sub-{sub}_acq-dwib0_dir-{direction}_epi.nii.gz"
        nb.nifti1.Nifti1Image(np.zeros((4, 4)), affine=np.eye(4)).to_filename(
            img
        )
        sidecar_api = fmapdir / img.name.replace(".nii.gz", ".json")
        ped = "i" if direction == "AP" else "i-"
        sidecar_api.write_text(
            json.dumps({"PhaseEncodingDirection": ped, "TotalReadoutTime": 1})
        )

    test_layout = bids.BIDSLayout(bidsdir)
    img_file: bids.layout.models.BIDSImageFile = test_layout.get(
        subject=sub, suffix="epi", extension=".nii.gz", direction="AP"
    )[0]
    # show bids file
    print(f"{img_file=}")
    entities = img_file.get_entities()
    entities_with_extension = {
        **{k: v for k, v in entities.items() if k != "extension"},
        **{"extension": ".json"},
    }
    # confirm that the new entities has the .json ending
    # (but what's that extra fmap: epi?)
    print(f"{entities_with_extension=}")
    files = test_layout.get(**entities_with_extension)
    # this is empty?
    print(f"{files=}")

    files_without_fmap_entity = test_layout.get(
        **{k: v for k, v in entities_with_extension.items() if k != "fmap"}
    )
    # seems like the issue was the extra fmap entity
    print(f"{files_without_fmap_entity=}")
img_file=<BIDSImageFile filename='/var/folders/v_/kcpb096s1m3_37ctfd2sp2xm0000gn/T/tmpq0b7dk7z/sub-0/fmap/sub-0_acq-dwib0_dir-AP_epi.nii.gz'>

entities_with_extension={'acquisition': 'dwib0', 'datatype': 'fmap', 'direction': 'AP', 'fmap': 'epi', 'subject': '0', 'suffix': 'epi', 'extension': '.json'}

files=[]

files_without_fmap_entity=[<BIDSJSONFile filename='/var/folders/v_/kcpb096s1m3_37ctfd2sp2xm0000gn/T/tmpiwo5vuhu/sub-0/fmap/sub-0_acq-dwib0_dir-AP_epi.json'>]
bids.__version__
'0.16.5'
@effigies
Copy link
Collaborator

If all you want to do is get the same file but .json, then I think bidsfile.path.replace(file.entities['extension'], '.json') will do the trick.

The entities are a bit of a mess, due to the conflation of all path components (and, as you note, fmap) in entities.

{
"name": "fmap",
"pattern": "(phasediff|magnitude[1-2]|phase[1-2]|fieldmap|epi)\\.nii"
},

It seems unlikely that anybody's using that undocumented "entity", that is just the same as suffix for fieldmaps, but removing it properly would take a deprecation cycle. Feel free to add a config option:

https://github.com/bids-standard/pybids/blob/master/bids/config.py

There's not a lot of churn, so the deprecation is likely to take a while, but there's no reason we can't start it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants