Skip to content

Commit 91e4a3c

Browse files
committed
start writing script for updating bids uri
1 parent d4a925c commit 91e4a3c

File tree

4 files changed

+135
-41
lines changed

4 files changed

+135
-41
lines changed

tools/check_intended_for.py

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,52 +20,59 @@
2020
"IntendedFor": ["bids::sub-01/anat/sub-01_T1w.nii.gz"]
2121
"""
2222

23-
from pathlib import Path
2423
import json
25-
from warnings import warn
26-
from rich import print
24+
from pathlib import Path
2725

2826
VERBOSE = False
2927

30-
root_dir = Path(__file__).parent.parent
3128

32-
deprecated_formats = {}
29+
def root_dir():
30+
return Path(__file__).parent.parent
31+
3332

34-
for json_path in root_dir.glob("**/*.json"):
33+
def main():
34+
deprecated_formats = {}
3535

36-
if VERBOSE:
37-
print(f"Checking {json_path.relative_to(root_dir)}")
36+
for json_path in root_dir().glob("**/*.json"):
37+
if VERBOSE:
38+
print(f"Checking {json_path.relative_to(root_dir())}")
3839

39-
with open(json_path) as f:
40-
content = json.load(f)
40+
with open(json_path) as f:
41+
content = json.load(f)
42+
43+
if "IntendedFor" not in content:
44+
continue
4145

42-
if "IntendedFor" in content:
4346
intended_for = content["IntendedFor"]
4447
if isinstance(intended_for, str):
4548
intended_for = [intended_for]
4649

4750
for intended_for_path in intended_for:
48-
if not intended_for_path.startswith("bids"):
49-
if json_path not in deprecated_formats:
50-
deprecated_formats[json_path] = []
51-
deprecated_formats[json_path].append(intended_for_path)
52-
53-
if deprecated_formats:
54-
55-
log_file = root_dir / "deprecated_intended_for.log"
56-
57-
with open(log_file, "w") as f:
58-
for json_path, deprecated_paths in deprecated_formats.items():
59-
f.write(f"{json_path.relative_to(root_dir)}\n")
60-
print(f"{json_path.relative_to(root_dir)}")
61-
for deprecated_path in deprecated_paths:
62-
f.write(f" {deprecated_path}\n")
63-
print(f" {deprecated_path}")
64-
65-
raise(ValueError)(
66-
f"Found {len(deprecated_formats)} jsons with deprecated IntendedFor formats.\n"
67-
f"See {log_file}\n"
68-
"Please update them to the new format.\n"
69-
"See https://bids-specification.readthedocs.io/en/latest/common-principles.html#bids-uri"
70-
)
71-
51+
if intended_for_path.startswith("bids:"):
52+
continue
53+
54+
if json_path not in deprecated_formats:
55+
deprecated_formats[json_path] = []
56+
deprecated_formats[json_path].append(intended_for_path)
57+
58+
if deprecated_formats:
59+
log_file = root_dir() / "deprecated_intended_for.log"
60+
61+
with open(log_file, "w") as f:
62+
for json_path, deprecated_paths in deprecated_formats.items():
63+
f.write(f"{json_path.relative_to(root_dir())}\n")
64+
print(f"{json_path.relative_to(root_dir())}")
65+
for deprecated_path in deprecated_paths:
66+
f.write(f" {deprecated_path}\n")
67+
print(f" {deprecated_path}")
68+
69+
raise (ValueError)(
70+
f"Found {len(deprecated_formats)} jsons with deprecated IntendedFor formats.\n"
71+
f"See {log_file}\n"
72+
"Please update them to the new format.\n"
73+
"See https://bids-specification.readthedocs.io/en/latest/common-principles.html#bids-uri"
74+
)
75+
76+
77+
if __name__ == "__main__":
78+
main()

tools/print_dataset_listing.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Take the listing of examples datasets
22
and turns it into a markdown document with a series of markdown tables."""
33
from pathlib import Path
4+
45
import pandas as pd
56
from bids import BIDSLayout
67

@@ -93,7 +94,7 @@ def update_datatypes_and_suffixes(df, root):
9394
def add_links(df):
9495
print("Adding hyperlinks in table...")
9596
for row in df.iterrows():
96-
for col in ["name","link to full data", "maintained by"]:
97+
for col in ["name", "link to full data", "maintained by"]:
9798
if not isinstance(row[1][col], str):
9899
continue
99100
if col == "name":
@@ -105,7 +106,6 @@ def add_links(df):
105106
return df
106107

107108

108-
109109
def clean_previous_run(output_file: Path) -> None:
110110
print("Cleaning output files from previous run...")
111111
lines = output_file.read_text().split("\n")
@@ -117,13 +117,17 @@ def clean_previous_run(output_file: Path) -> None:
117117
break
118118
f.write(line + "\n")
119119

120+
120121
def add_warning(f):
121-
f.write("""<!--
122+
f.write(
123+
"""<!--
122124
Table below is generated automatically.
123125
Do not edit directly.
124126
-->
125127
126-
""".upper())
128+
""".upper()
129+
)
130+
127131

128132
def add_tables(df: pd.DataFrame, output_file: Path) -> None:
129133
print("Writing markdown tables...")

tools/requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
pybids
22
pandas
3-
tabulate
4-
rich
3+
tabulate

tools/update_intended_for.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""Update jsons of all datasets for IntendedFor field to use proper format.
2+
3+
https://bids-specification.readthedocs.io/en/latest/common-principles.html#bids-uri
4+
5+
Example:
6+
7+
- bad
8+
9+
.. code-block:: json
10+
11+
"IntendedFor": ["anat/sub-01_T1w.nii.gz"]
12+
13+
14+
- good
15+
16+
.. code-block:: json
17+
18+
"IntendedFor": ["bids::sub-01/anat/sub-01_T1w.nii.gz"]
19+
"""
20+
21+
import json
22+
from pathlib import Path
23+
24+
from rich import print
25+
26+
VERBOSE = False
27+
28+
29+
def root_dir():
30+
return Path(__file__).parent.parent
31+
32+
33+
def main():
34+
for json_path in root_dir().glob("**/*.json"):
35+
36+
if VERBOSE:
37+
print(f"Checking {json_path.relative_to(root_dir())}")
38+
39+
with open(json_path) as f:
40+
content = json.load(f)
41+
42+
if "IntendedFor" not in content:
43+
continue
44+
45+
intended_for = content["IntendedFor"]
46+
47+
was_str = False
48+
if isinstance(intended_for, str):
49+
was_str = True
50+
intended_for = [intended_for]
51+
52+
for i, intended_for_path in enumerate(intended_for):
53+
if intended_for_path.startswith("bids:"):
54+
continue
55+
56+
if not intended_for_path.startswith(
57+
("ses-", "anat", "func", "ieeg", "fmap", "perf", "micr")
58+
):
59+
if VERBOSE:
60+
print(f"[red]will not update {intended_for_path}[/red]")
61+
continue
62+
63+
filename = Path(intended_for_path).name
64+
subject = filename.split("_")[0]
65+
66+
if intended_for_path.startswith("ses-"):
67+
session = intended_for_path.split("/")[0]
68+
datatype = intended_for_path.split("/")[1]
69+
uri = [subject, session, datatype, filename]
70+
else:
71+
datatype = intended_for_path.split("/")[0]
72+
uri = [subject, datatype, filename]
73+
74+
intended_for[i] = f"bids::{'/'.join(uri)}"
75+
76+
if was_str:
77+
intended_for = intended_for[0]
78+
79+
if VERBOSE:
80+
print(intended_for)
81+
82+
83+
if __name__ == "__main__":
84+
main()

0 commit comments

Comments
 (0)