-
Notifications
You must be signed in to change notification settings - Fork 128
/
individual.py
112 lines (94 loc) · 4.2 KB
/
individual.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
""" Encapsulates report generation functions """
def individual_html(in_iqms, in_plots=None, api_id=None):
from pathlib import Path
import datetime
from json import load
from .. import config
from ..utils.misc import BIDS_COMP
from ..reports import REPORT_TITLES
from ..reports.utils import iqms2html, read_report_snippet
from ..data import IndividualTemplate
def _get_details(in_iqms, modality):
in_prov = in_iqms.pop("provenance", {})
warn_dict = in_prov.pop("warnings", None)
sett_dict = in_prov.pop("settings", None)
wf_details = []
if modality == "bold":
bold_exclude_index = in_iqms.get("dumb_trs")
if bold_exclude_index is None:
config.loggers.cli.warning(
"Building bold report: no exclude index was found"
)
elif bold_exclude_index > 0:
msg = """\
<span class="problematic">Non-steady state (strong T1 contrast) has been detected in the \
first {} volumes</span>. They were excluded before generating any QC measures and plots."""
wf_details.append(msg.format(bold_exclude_index))
wf_details.append(
"Framewise Displacement was computed using <code>3dvolreg</code> (AFNI)")
fd_thres = sett_dict.pop("fd_thres")
if fd_thres is not None:
wf_details.append(
"Framewise Displacement threshold was defined at %f mm" % fd_thres
)
elif modality in ("T1w", "T2w"):
if warn_dict.pop("small_air_mask", False):
wf_details.append(
'<span class="problematic">Detected hat mask was too small</span>'
)
if warn_dict.pop("large_rot_frame", False):
wf_details.append(
'<span class="problematic">Detected a zero-filled frame, has the original '
"image been rotated?</span>"
)
return in_prov, wf_details, sett_dict
in_iqms = Path(in_iqms)
with in_iqms.open() as jsonfile:
iqms_dict = load(jsonfile)
# Now, the in_iqms file should be correctly named
out_file = str(Path(in_iqms.with_suffix(".html").name).resolve())
# Extract and prune metadata
metadata = iqms_dict.pop("bids_meta", None)
mod = metadata.pop("modality", None)
prov, wf_details, _ = _get_details(iqms_dict, mod)
file_id = [metadata.pop(k, None) for k in list(BIDS_COMP.keys())]
file_id = [comp for comp in file_id if comp is not None]
if in_plots is None:
in_plots = []
else:
if any(("melodic_reportlet" in k for k in in_plots)):
REPORT_TITLES["bold"].insert(3, ("ICA components", "ica-comps"))
if any(("plot_spikes" in k for k in in_plots)):
REPORT_TITLES["bold"].insert(3, ("Spikes", "spikes"))
in_plots = [
(REPORT_TITLES[mod][i] + (read_report_snippet(v),))
for i, v in enumerate(in_plots)
]
pred_qa = None # metadata.pop('mriqc_pred', None)
_config = {
"modality": mod,
"dataset": metadata.pop("dataset", None),
"bids_name": in_iqms.with_suffix("").name,
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d, %H:%M"),
"version": config.environment.version,
"imparams": iqms2html(iqms_dict, "iqms-table"),
"svg_files": in_plots,
"workflow_details": wf_details,
"webapi_url": prov.pop("webapi_url"),
"webapi_port": prov.pop("webapi_port"),
"provenance": iqms2html(prov, "provenance-table"),
"md5sum": prov["md5sum"],
"metadata": iqms2html(metadata, "metadata-table"),
"pred_qa": pred_qa,
}
if _config["metadata"] is None:
_config["workflow_details"].append(
'<span class="warning">File has no metadata</span> '
"<span>(sidecar JSON file missing or empty)</span>"
)
tpl = IndividualTemplate()
tpl.generate_conf(_config, out_file)
config.loggers.cli.info("Generated individual log (%s)", out_file)
return out_file