Skip to content

Instantly share code, notes, and snippets.

@tsalo
Last active November 6, 2019 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsalo/da6d8a49b2a4afb7e7cfbf3283920b74 to your computer and use it in GitHub Desktop.
Save tsalo/da6d8a49b2a4afb7e7cfbf3283920b74 to your computer and use it in GitHub Desktop.
Some pseudocode implementing a tedana decision tree node according to a proposed specification.
from textwrap import dedent
import logging
LGR = logging.getLogger(__name__)
def list_to_str(lst, joiner='and'):
if len(lst) == 1:
return lst[0]
elif len(lst) == 2:
return ' {} '.format(joiner).join(lst)
else:
str_ = ', '.join(lst[:-1]) + ', {} '.format(joiner) + lst[-1]
return str_
def decision_tree_step(comptable, if_true='reject', if_false='no_change',
decide_comps=('unclassified', 'provisional_accept', 'provisional_reject'),
x_thresh=0.5, f_r2_clustermaps=None, return_metrics=False,
decision_tree_steps=None):
metrics_used = ['metric']
state_enum = 'decision_tree_step'
config = {'decision_tree_step': {
'metrics_used': metrics_used,
'variables_used': {
'if_true': if_true,
'if_false': if_false,
'decide_comps': decide_comps,
'x_thresh': x_thresh,
# don't want to store actual maps, but a bool describing whether
# or not they were used at all could be good
'f_r2_clustermaps': f_r2_clustermaps is not None,
}
}
}
# Actual decision step
reduced_comptable = comptable.loc[comptable['classification'].isin(decide_comps)]
classification_index = reduced_comptable['metric'] > x_thresh
if if_true != 'no_change':
reduced_comptable.loc[classification_index, 'classification'] = if_true
if if_false != 'no_change':
reduced_comptable.loc[~classification_index, 'classification'] = if_false
comptable.loc[reduced_comptable.index, 'classification'] = reduced_comptable['classification']
comptable.loc[reduced_comptable.index, 'state'] += (state_enum + ';')
description = dedent"""\
Components classified as {} were subselected for further classification
using the "decision_tree_step" method, in which components with an x_thresh
greater than {} are classified as "{}" and those with values below the
threshold are classified as "{}".
""".format(list_to_str(decide_comps, 'or'), x_thresh, if_true, if_false)
LGR.info(description)
decision_tree_steps.append(config)
return comptable, metrics_used, description, decision_tree_steps
def metric_node(comptable, Br_R2_clmaps, F_R2_clmaps, metric_name='dice_FR2'):
assert comptable.shape[0] == Br_R2_clmaps.shape[1] == F_R2_clmaps.shape[1]
comptable[metric_name] = np.zeros(comptable.shape[0])
for i_comp in comptable.index:
comptable.loc[i_comp, 'dice_FR2'] = utils.dice(Br_R2_clmaps[:, i_comp],
F_R2_clmaps[:, i_comp])
comptable.loc[np.isnan(comptable['dice_FR2']), 'dice_FR2'] = 0
description = dedent"""\
The "{}" metric was calculated as the Dice coefficient of masked,
cluster-extent thresholded F-statistics and beta-value maps.
""".format(metric_name)
LGR.info(description)
return comptable, description
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment