|
a |
|
b/utils/brainweb_download.py |
|
|
1 |
from dataclasses import dataclass |
|
|
2 |
from pathlib import Path |
|
|
3 |
|
|
|
4 |
import numpy as np |
|
|
5 |
import requests |
|
|
6 |
from nibabel import load, save, Nifti1Image |
|
|
7 |
from tqdm import tqdm |
|
|
8 |
|
|
|
9 |
|
|
|
10 |
@dataclass |
|
|
11 |
class Item: |
|
|
12 |
url: str |
|
|
13 |
path: str |
|
|
14 |
severity: str |
|
|
15 |
|
|
|
16 |
|
|
|
17 |
def _download(url: str, data: str, fname: str): |
|
|
18 |
resp = requests.post(url, data=data, stream=True) |
|
|
19 |
total = int(resp.headers.get('content-length', 0)) |
|
|
20 |
with open(fname, 'wb') as file, tqdm( |
|
|
21 |
desc=fname, |
|
|
22 |
total=total, |
|
|
23 |
unit='iB', |
|
|
24 |
unit_scale=True, |
|
|
25 |
unit_divisor=1024, |
|
|
26 |
) as bar: |
|
|
27 |
for data in resp.iter_content(chunk_size=1024): |
|
|
28 |
size = file.write(data) |
|
|
29 |
bar.update(size) |
|
|
30 |
|
|
|
31 |
|
|
|
32 |
def _download_and_convert( |
|
|
33 |
url: str, fname: Path, alias: str, name: str, institution: str, |
|
|
34 |
email: str, force_update: bool = False |
|
|
35 |
): |
|
|
36 |
minc_fname = fname.with_suffix('.mnc.gz') |
|
|
37 |
fname.parent.mkdir(parents=True, exist_ok=True) |
|
|
38 |
if minc_fname.exists() and not force_update: |
|
|
39 |
print( |
|
|
40 |
f"Skipping {str(minc_fname)} download, " |
|
|
41 |
f"since it already exists." |
|
|
42 |
) |
|
|
43 |
else: |
|
|
44 |
_download( |
|
|
45 |
url=url, |
|
|
46 |
data=f'do_download_alias={alias}' |
|
|
47 |
f'&format_value=minc' |
|
|
48 |
f'&zip_value=gnuzip' |
|
|
49 |
f'&who_name={name}' |
|
|
50 |
f'&who_institution={institution}' |
|
|
51 |
f'&who_email={email}' |
|
|
52 |
f'&download_for_real=%5BStart+download%21%5D', |
|
|
53 |
fname=str(minc_fname) |
|
|
54 |
) |
|
|
55 |
nii_fname = fname.with_suffix('.nii.gz') |
|
|
56 |
if nii_fname.exists() and not force_update: |
|
|
57 |
print( |
|
|
58 |
f"Skipping conversion of {str(minc_fname)}, " |
|
|
59 |
f"since {str(nii_fname)} already exists." |
|
|
60 |
) |
|
|
61 |
else: |
|
|
62 |
try: |
|
|
63 |
minc = load(minc_fname) |
|
|
64 |
affine = np.array([[0, 0, 1, 0], |
|
|
65 |
[0, 1, 0, 0], |
|
|
66 |
[1, 0, 0, 0], |
|
|
67 |
[0, 0, 0, 1]]) |
|
|
68 |
out = Nifti1Image(minc.get_fdata(), affine=affine) |
|
|
69 |
save(out, nii_fname) |
|
|
70 |
print(f'Successfully converted to {str(nii_fname)}') |
|
|
71 |
except Exception as e: |
|
|
72 |
print(e) |
|
|
73 |
|
|
|
74 |
|
|
|
75 |
def _download_data(base_dir, name, institution, email): |
|
|
76 |
modality = 'T2' |
|
|
77 |
slice_thickness = '1mm' |
|
|
78 |
noise_levels = ['pn0', 'pn1', 'pn3', 'pn5'] |
|
|
79 |
intensity_non_uniformities = ['rf0', 'rf20', 'rf40'] |
|
|
80 |
severities = [ |
|
|
81 |
Item( |
|
|
82 |
url='https://brainweb.bic.mni.mcgill.ca/cgi/brainweb2', |
|
|
83 |
path='lesions/severe', |
|
|
84 |
severity='AI+msles2' |
|
|
85 |
), |
|
|
86 |
Item( |
|
|
87 |
url='https://brainweb.bic.mni.mcgill.ca/cgi/brainweb1', |
|
|
88 |
path='normal', |
|
|
89 |
severity='ICBM+normal' |
|
|
90 |
) |
|
|
91 |
] |
|
|
92 |
|
|
|
93 |
for item in severities: |
|
|
94 |
out_dir = (base_dir / item.path) |
|
|
95 |
for noise_level in noise_levels: |
|
|
96 |
for intensity_non_uniformity in intensity_non_uniformities: |
|
|
97 |
alias = f"{modality}+{item.severity}+{slice_thickness}+{noise_level}+{intensity_non_uniformity}" |
|
|
98 |
fname = out_dir / alias.replace("+", "_").lower() |
|
|
99 |
_download_and_convert( |
|
|
100 |
url=item.url, |
|
|
101 |
fname=fname, |
|
|
102 |
alias=alias, |
|
|
103 |
name=name, |
|
|
104 |
institution=institution, |
|
|
105 |
email=email |
|
|
106 |
) |
|
|
107 |
|
|
|
108 |
|
|
|
109 |
def _download_labels(base_dir, name, institution, email): |
|
|
110 |
items = [ |
|
|
111 |
Item( |
|
|
112 |
url="https://brainweb.bic.mni.mcgill.ca/cgi/brainweb1", |
|
|
113 |
path="normal", |
|
|
114 |
severity="phantom_1.0mm_normal_crisp" |
|
|
115 |
), # normal |
|
|
116 |
Item( |
|
|
117 |
url="https://brainweb.bic.mni.mcgill.ca/cgi/brainweb2", |
|
|
118 |
path="severe_lesions", |
|
|
119 |
severity="phantom_1.0mm_msles3_crisp" |
|
|
120 |
) # severe |
|
|
121 |
] |
|
|
122 |
|
|
|
123 |
gt_dir = (base_dir / 'groundtruth') |
|
|
124 |
for item in items: |
|
|
125 |
_download_and_convert( |
|
|
126 |
url=item.url, |
|
|
127 |
fname=gt_dir / item.path, |
|
|
128 |
alias=item.severity, |
|
|
129 |
name=name, |
|
|
130 |
institution=institution, |
|
|
131 |
email=email |
|
|
132 |
) |
|
|
133 |
|
|
|
134 |
|
|
|
135 |
def download_brainweb_dataset( |
|
|
136 |
# default path for google colab example |
|
|
137 |
base_dir: Path = Path('/content/data/Brainweb'), |
|
|
138 |
name: str = "", |
|
|
139 |
institution: str = "", |
|
|
140 |
email: str = "", |
|
|
141 |
): |
|
|
142 |
_download_data(base_dir, name, institution, email) |
|
|
143 |
_download_labels(base_dir, name, institution, email) |