Skip to content

Commit 81765a2

Browse files
authored
Merge pull request #1041 from arnaudbore/fix_convert_json_xlsx
[ENH][BF] Update json conversion to excel used in tractometry_flow
2 parents b95593b + 2a06733 commit 81765a2

File tree

2 files changed

+91
-101
lines changed

2 files changed

+91
-101
lines changed

scripts/scil_bundle_shape_measures.py

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -215,70 +215,68 @@ def main():
215215
pool.join()
216216

217217
output_measures_dict = {}
218-
for measure_dict in all_measures_dict:
219-
# Empty bundle should not make the script crash
220-
if measure_dict is not None:
221-
for measure_name in measure_dict.keys():
222-
# Create an empty list first
223-
if measure_name not in output_measures_dict:
224-
output_measures_dict[measure_name] = []
225-
output_measures_dict[measure_name].append(
226-
measure_dict[measure_name])
227-
# add group stats if user wants
228-
if args.group_statistics:
229-
# length and span are weighted by streamline count
230-
group_total_length = np.sum(
231-
np.multiply(output_measures_dict['avg_length'],
232-
output_measures_dict['streamlines_count']))
233-
group_total_span = np.sum(
234-
np.multiply(output_measures_dict['span'],
235-
output_measures_dict['streamlines_count']))
236-
group_streamlines_count = \
237-
np.sum(output_measures_dict['streamlines_count'])
238-
group_avg_length = group_total_length / group_streamlines_count
239-
group_avg_span = group_total_span / group_streamlines_count
240-
group_avg_vol = np.average(output_measures_dict['volume'])
241-
group_avg_diam = \
242-
2 * np.sqrt(group_avg_vol / (np.pi * group_avg_length))
243-
output_measures_dict['group_stats'] = {}
244-
output_measures_dict['group_stats']['total_streamlines_count'] = \
245-
float(group_streamlines_count)
246-
output_measures_dict['group_stats']['avg_streamline_length'] = \
247-
group_avg_length
248-
# max and min length of all streamlines in all input bundles
249-
output_measures_dict['group_stats']['max_streamline_length'] = \
250-
float(np.max(output_measures_dict['max_length']))
251-
output_measures_dict['group_stats']['min_streamline_length'] = \
252-
float(np.min(output_measures_dict['min_length']))
253-
output_measures_dict['group_stats']['avg_streamline_span'] = \
254-
group_avg_span
255-
# computed with other set averages and not weighted by streamline count
256-
output_measures_dict['group_stats']['avg_volume'] = group_avg_vol
257-
output_measures_dict['group_stats']['avg_curl'] = \
258-
group_avg_length / group_avg_span
259-
output_measures_dict['group_stats']['avg_diameter'] = group_avg_diam
260-
output_measures_dict['group_stats']['avg_elongation'] = \
261-
group_avg_length / group_avg_diam
262-
output_measures_dict['group_stats']['avg_surface_area'] = \
263-
np.average(output_measures_dict['surface_area'])
264-
output_measures_dict['group_stats']['avg_irreg'] = \
265-
np.average(output_measures_dict['irregularity'])
266-
output_measures_dict['group_stats']['avg_end_surface_area_head'] = \
267-
np.average(output_measures_dict['end_surface_area_head'])
268-
output_measures_dict['group_stats']['avg_end_surface_area_tail'] = \
269-
np.average(output_measures_dict['end_surface_area_tail'])
270-
output_measures_dict['group_stats']['avg_radius_head'] = \
271-
np.average(output_measures_dict['radius_head'])
272-
output_measures_dict['group_stats']['avg_radius_tail'] = \
273-
np.average(output_measures_dict['radius_tail'])
274-
output_measures_dict['group_stats']['avg_irregularity_head'] = \
275-
np.average(
276-
output_measures_dict['irregularity_of_end_surface_head'])
277-
output_measures_dict['group_stats']['avg_irregularity_tail'] = \
278-
np.average(
279-
output_measures_dict['irregularity_of_end_surface_tail'])
280-
output_measures_dict['group_stats']['avg_fractal_dimension'] = \
281-
np.average(output_measures_dict['fractal_dimension'])
218+
if len(args.in_bundles) == 1:
219+
output_measures_dict = all_measures_dict[0]
220+
else:
221+
for measure_dict in all_measures_dict:
222+
# Empty bundle should not make the script crash
223+
if measure_dict is not None:
224+
for measure_name in measure_dict.keys():
225+
# Create an empty list first
226+
if measure_name not in output_measures_dict:
227+
output_measures_dict[measure_name] = []
228+
output_measures_dict[measure_name].append(
229+
measure_dict[measure_name])
230+
# add group stats if user wants
231+
if args.group_statistics:
232+
# length and span are weighted by streamline count
233+
group_total_length = np.sum(
234+
np.multiply(output_measures_dict['avg_length'],
235+
output_measures_dict['streamlines_count']))
236+
group_total_span = np.sum(
237+
np.multiply(output_measures_dict['span'],
238+
output_measures_dict['streamlines_count']))
239+
group_streamlines_count = \
240+
np.sum(output_measures_dict['streamlines_count'])
241+
group_avg_length = group_total_length / group_streamlines_count
242+
group_avg_span = group_total_span / group_streamlines_count
243+
group_avg_vol = np.average(output_measures_dict['volume'])
244+
group_avg_diam = \
245+
2 * np.sqrt(group_avg_vol / (np.pi * group_avg_length))
246+
output_measures_dict['group_stats'] = {}
247+
output_measures_dict['group_stats']['total_streamlines_count'] = \
248+
float(group_streamlines_count)
249+
output_measures_dict['group_stats']['avg_streamline_length'] = \
250+
group_avg_length
251+
# max and min length of all streamlines in all input bundles
252+
output_measures_dict['group_stats']['max_streamline_length'] = \
253+
float(np.max(output_measures_dict['max_length']))
254+
output_measures_dict['group_stats']['min_streamline_length'] = \
255+
float(np.min(output_measures_dict['min_length']))
256+
output_measures_dict['group_stats']['avg_streamline_span'] = \
257+
group_avg_span
258+
# computed with other set averages and not weighted by
259+
# streamline count
260+
output_measures_dict['group_stats']['avg_volume'] = group_avg_vol
261+
output_measures_dict['group_stats']['avg_curl'] = \
262+
group_avg_length / group_avg_span
263+
output_measures_dict['group_stats']['avg_diameter'] = group_avg_diam
264+
output_measures_dict['group_stats']['avg_elongation'] = \
265+
group_avg_length / group_avg_diam
266+
output_measures_dict['group_stats']['avg_irregularity_head'] = \
267+
np.average(
268+
output_measures_dict['irregularity_of_end_surface_head'])
269+
output_measures_dict['group_stats']['avg_irregularity_tail'] = \
270+
np.average(
271+
output_measures_dict['irregularity_of_end_surface_tail'])
272+
273+
list_metrics = ['surface_area', 'irregularity',
274+
'end_surface_area_head',
275+
'end_surface_area_tail', 'radius_head',
276+
'radius_tail', 'fractal_dimension']
277+
for curr_metric in list_metrics:
278+
output_measures_dict['group_stats']['avg_' + curr_metric] = \
279+
np.average(output_measures_dict[curr_metric])
282280

283281
if args.out_json:
284282
with open(args.out_json, 'w') as outfile:

scripts/scil_json_convert_entries_to_xlsx.py

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from scilpy.io.utils import (add_overwrite_arg, add_verbose_arg,
1919
assert_inputs_exist, assert_outputs_exist)
2020

21+
dps_dpp = ['data_per_streamline_keys', 'data_per_point_keys']
22+
2123

2224
def _get_all_bundle_names(stats):
2325
bnames = set()
@@ -73,20 +75,16 @@ def _get_stats_parse_function(stats, stats_over_population):
7375
first_bundle_stats.keys())[0]]
7476

7577
if len(first_bundle_stats.keys()) == 1 and\
76-
_are_all_elements_scalars(first_bundle_stats):
78+
_are_all_elements_scalars(first_bundle_stats): # when you have only on key per bundle
7779
return _parse_scalar_stats
78-
elif len(first_bundle_stats.keys()) == 4 and \
80+
if len(first_bundle_stats.keys()) == 4 and \
7981
set(first_bundle_stats.keys()) == \
8082
set(['lesion_total_vol', 'lesion_avg_vol', 'lesion_std_vol',
81-
'lesion_count']):
83+
'lesion_count']): # when you have lesion stats
8284
return _parse_lesion
83-
elif len(first_bundle_stats.keys()) == 4 and \
84-
set(first_bundle_stats.keys()) == \
85-
set(['min_length', 'max_length', 'mean_length', 'std_length']):
86-
return _parse_lengths
8785
elif type(first_bundle_substat) is dict:
8886
sub_keys = list(first_bundle_substat.keys())
89-
if set(sub_keys) == set(['mean', 'std']):
87+
if set(sub_keys) == set(['mean', 'std']): # when you have mean and std per stats
9088
if stats_over_population:
9189
return _parse_per_label_population_stats
9290
else:
@@ -95,6 +93,8 @@ def _get_stats_parse_function(stats, stats_over_population):
9593
return _parse_per_point_meanstd
9694
elif _are_all_elements_scalars(first_bundle_substat):
9795
return _parse_per_label_scalar
96+
else: # when you have multiple metrics per bundle
97+
return _parse_stats
9898

9999
raise IOError('Unable to recognize stats type!')
100100

@@ -201,39 +201,31 @@ def _parse_scalar_lesions(stats, subs, bundles):
201201
return dataframes, df_names
202202

203203

204-
def _parse_lengths(stats, subs, bundles):
204+
def _parse_stats(stats, subs, bundles):
205205
nb_subs = len(subs)
206206
nb_bundles = len(bundles)
207207

208-
min_lengths = np.full((nb_subs, nb_bundles), np.NaN)
209-
max_lengths = np.full((nb_subs, nb_bundles), np.NaN)
210-
mean_lengths = np.full((nb_subs, nb_bundles), np.NaN)
211-
std_lengths = np.full((nb_subs, nb_bundles), np.NaN)
212-
213-
for sub_id, sub_name in enumerate(subs):
214-
for bundle_id, bundle_name in enumerate(bundles):
215-
b_stat = stats[sub_name].get(bundle_name)
216-
217-
if b_stat is not None:
218-
min_lengths[sub_id, bundle_id] = b_stat['min_length']
219-
max_lengths[sub_id, bundle_id] = b_stat['max_length']
220-
mean_lengths[sub_id, bundle_id] = b_stat['mean_length']
221-
std_lengths[sub_id, bundle_id] = b_stat['std_length']
222-
223-
dataframes = [pd.DataFrame(data=min_lengths,
224-
index=subs,
225-
columns=bundles),
226-
pd.DataFrame(data=max_lengths,
227-
index=subs,
228-
columns=bundles),
229-
pd.DataFrame(data=mean_lengths,
230-
index=subs,
231-
columns=bundles),
232-
pd.DataFrame(data=std_lengths,
233-
index=subs,
234-
columns=bundles)]
208+
dataframes = []
235209

236-
df_names = ["min_length", "max_length", "mean_length", "std_length"]
210+
# Check all metrics keys
211+
metrics_keys = stats[subs[0]][bundles[0]].keys()
212+
df_names = list(metrics_keys)
213+
214+
for metric_name in metrics_keys:
215+
if metric_name in dps_dpp: # remove dps and dpp keys
216+
df_names.remove(metric_name)
217+
else:
218+
curr_metric = np.full((nb_subs, nb_bundles), np.NaN)
219+
for bundle_id, bundle_name in enumerate(bundles):
220+
for sub_id, sub_name in enumerate(subs):
221+
b_stat = stats[sub_name][bundle_name].get(metric_name)
222+
if b_stat is not None:
223+
curr_metric[sub_id, bundle_id] = b_stat
224+
225+
dataframes.append(pd.DataFrame(data=curr_metric,
226+
index=subs,
227+
columns=bundles))
228+
del curr_metric
237229

238230
return dataframes, df_names
239231

0 commit comments

Comments
 (0)