Skip to content

Commit

Permalink
ENH: add HeudiconvVersion to sidecar .json files
Browse files Browse the repository at this point in the history
Unfortunately there is no convention yet in BIDS on storing such information in
a standardized way.

bids-standard/bids-specification#440
 proposes to add GeneratedBy (within dataset_description.json)
 which could provide detailed high level information which should then be
 consistent through out dataset (so we would need to add safeguards)

bids-standard/bids-specification#487
 is WiP to introduce PROV into BIDS standard, which would allow to establish
 _prov.json with all needed gory details.

For now, since fields in side car .json files are not strictly regulated,
I think it would be benefitial to user to have heudiconv version stored there
along with other "Version" fields, such as

	$> grep -e Version -e dcm2ni fmap/sub-phantom1sid1_ses-localizer_acq-3mm_phasediff.json
	  "ConversionSoftware": "dcm2niix",
	  "ConversionSoftwareVersion": "v1.0.20211006",
	  "SoftwareVersions": "syngo MR E11",

and although strictly speaking Heudiconv is a "conversion software", since
dcm2niix decided to use that pair, I have decided to leave it alone and just
come up with yet another descriptive key

  "HeudiconvVersion": "0.10.0",
  • Loading branch information
yarikoptic committed Oct 11, 2021
1 parent 460a818 commit ee0dcb0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
9 changes: 9 additions & 0 deletions heudiconv/bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
is_readonly,
get_datetime,
)
from . import __version__

lgr = logging.getLogger(__name__)

Expand All @@ -40,6 +41,10 @@
("Description", "md5 hash of UIDs")])),
])

#: JSON Key where we will embed our version in the newly produced .json files
HEUDICONV_VERSION_JSON_KEY = 'HeudiconvVersion'


class BIDSError(Exception):
pass

Expand Down Expand Up @@ -244,6 +249,10 @@ def tuneup_bids_json_files(json_files):
# Let's hope no word 'Date' comes within a study name or smth like
# that
raise ValueError("There must be no dates in .json sidecar")
# Those files should not have our version field already - should have been
# freshly produced
assert HEUDICONV_VERSION_JSON_KEY not in json_
json_[HEUDICONV_VERSION_JSON_KEY] = str(__version__)
save_json(jsonfile, json_)

# Load the beast
Expand Down
31 changes: 21 additions & 10 deletions heudiconv/tests/test_heuristics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

from glob import glob
from os.path import join as pjoin, dirname
from pathlib import Path
import csv
import re

from .. import __version__
from ..bids import HEUDICONV_VERSION_JSON_KEY
from ..utils import load_json

import pytest
from .utils import TESTS_DATA_PATH

Expand Down Expand Up @@ -140,16 +145,22 @@ def test_scout_conversion(tmpdir):
).split(' ') + ['-o', tmppath]
runner(args)

assert not op.exists(pjoin(
tmppath,
'Halchenko/Yarik/950_bids_test4/sub-phantom1sid1/ses-localizer/anat'))

assert op.exists(pjoin(
tmppath,
'Halchenko/Yarik/950_bids_test4/sourcedata/sub-phantom1sid1/'
'ses-localizer/anat/sub-phantom1sid1_ses-localizer_scout.dicom.tgz'
)
)
dspath = Path(tmppath) / 'Halchenko/Yarik/950_bids_test4'
sespath = dspath / 'sub-phantom1sid1/ses-localizer'

assert not (sespath / 'anat').exists()
assert (
dspath /
'sourcedata/sub-phantom1sid1/ses-localizer/'
'anat/sub-phantom1sid1_ses-localizer_scout.dicom.tgz'
).exists()

# Let's do some basic checks on produced files
j = load_json(sespath / 'fmap/sub-phantom1sid1_ses-localizer_acq-3mm_phasediff.json')
# We store HeuDiConv version in each produced .json file
# TODO: test that we are not somehow overwritting that version in existing
# files which we have not produced in a particular run.
assert j[HEUDICONV_VERSION_JSON_KEY] == __version__


@pytest.mark.parametrize(
Expand Down

0 comments on commit ee0dcb0

Please sign in to comment.