Source code for monte_carlo_analysis.metrics.BRATSMetric

"""
**Author** : Robin Camarasa

**Institution** : Erasmus Medical Center

**Position** : PhD student

**Contact** : r.camarasa@erasmusmc.nl

**Date** : 2020-10-27

**Project** : monte_carlo_analysis

**Implement class BRATSMetric**

"""
from monte_carlo_analysis.metrics import Metric
import numpy as np
from sklearn.metrics import auc, confusion_matrix
from numba import jit


[docs]class BRATSMetric(Metric): """ Implement BRATSMetric, This metric only work in binary context """ def __init__(self, threshold=100, epsilon=10**(-9)): super(BRATSMetric, self) self.threshold = threshold self.epsilon = epsilon self.integration_range = np.linspace(0, 1, self.threshold) def __call__( self, prediction: np.array, uncertainty_map: np.array, ground_truth: np.array, ): """ Compute the BRATS Metric """ classwise_prediction = np.argmax( prediction.mean(axis=0), axis=0 ) # Uncertainty map uncertainty_map /= np.max(uncertainty_map) results = [] # Loop over the class for class_ in range(prediction.shape[1]): # Get the class prediction class_prediction = classwise_prediction == class_ class_ground_truth = ground_truth[class_] class_uncertainty_map = uncertainty_map[class_] # Compute tp, fn, fp and tn maps tp = class_prediction * class_ground_truth fp = class_prediction * (1 - class_ground_truth) fn =(1 - class_prediction) * class_ground_truth tn =(1 - class_prediction) * (1 - class_ground_truth) # Compute value for threshold = 1.00 tp_1 = tp.sum() tn_1 = tn.sum() tpr = [] tnr = [] dice = [] # Compute the values of threshold for threshold in self.integration_range.tolist(): filtered_voxels = np.where(class_uncertainty_map < 1 - threshold) tp_, fn_, fp_, tn_ = tp[filtered_voxels].sum(), fn[filtered_voxels].sum(),\ fp[filtered_voxels].sum(), tn[filtered_voxels].sum() if tp_1 == 0: tpr.append(1) else: tpr.append((tp_1 - tp_)/(tp_1 + self.epsilon)) if tn_1 == 0: tnr.append(1) else: tnr.append((tn_1 - tn_)/(tn_1 + self.epsilon)) dice.append((2 * tp_) / (2 * tp_ + fp_ + fn_ + self.epsilon)) # Transform to array and remove nan values tpr = np.array(tpr) tpr[-1] = 1 tnr = np.array(tnr) tnr[-1] = 1 dice = np.array(dice) dice[-1] = 1 results.append( ( 2 - auc(self.integration_range, tpr) -\ auc(self.integration_range, tnr) +\ auc(self.integration_range, dice) )/3 ) return results