import os
import os.path as osp
from collections import OrderedDict
from functools import reduce
import pandas as pd
import mmcv
import numpy as np
from mmcv.utils import print_log
from prettytable import PrettyTable
from torch.utils.data import Dataset

from mmseg.core import eval_metrics
from mmseg.utils import get_root_logger
from .builder import DATASETS
from .pipelines import Compose

def get_paths_by_chip(image_level_df, auxiliary_img_suffixes):
    """
    Returns a chip-level dataframe with pivoted columns
    for vv_path and vh_path.

    Args:
        image_level_df (pd.DataFrame): image-level dataframe

    Returns:
        chip_level_df (pd.DataFrame): chip-level dataframe
    """
    paths = []

    for chip, group in image_level_df.groupby("chip_id"):
        vv_path = group[group.polarization == "vv"]["feature_path"].values[0]
        vh_path = group[group.polarization == "vh"]["feature_path"].values[0]
        auxiliary_paths = []

        for suffix in auxiliary_img_suffixes:
            auxiliary_paths.append(os.path.join(group["auxiliary_dir"].values[0], chip + suffix + '.tif'))
        paths.append([chip, vv_path, vh_path] + auxiliary_paths)

    columns_name = ["chip_id", "vv_path", "vh_path"]
    for suffix in auxiliary_img_suffixes: columns_name.append(suffix[1:].replace('-', '_'))
    return pd.DataFrame(paths, columns=columns_name)


@DATASETS.register_module()
class FloodDataSet(Dataset):

    CLASSES = None

    PALETTE = None

    def __init__(self,
                 pipeline,
                 img_dir,
                 auxiliary_img_dir=None,
                 auxiliary_img_suffixes=['_jrc-gsw-change', '_jrc-gsw-transitions', '_jrc-gsw-seasonality', \
                                         '_jrc-gsw-recurrence', '_jrc-gsw-occurrence',  '_jrc-gsw-extent', '_nasadem'],
                 ann_dir=None,
                 split=None,
                 data_root=None,
                 test_mode=False,
                 ignore_index=255,
                 reduce_zero_label=False,
                 classes=None,
                 palette=None):
        self.pipeline = Compose(pipeline)
        self.img_dir = img_dir
        self.auxiliary_img_dir = auxiliary_img_dir
        self.auxiliary_img_suffixes = auxiliary_img_suffixes
        self.ann_dir = ann_dir
        self.split = split
        self.data_root = data_root
        self.test_mode = test_mode
        self.ignore_index = ignore_index
        self.reduce_zero_label = reduce_zero_label
        self.label_map = None
        self.CLASSES, self.PALETTE = self.get_classes_and_palette(
            classes, palette)


        # join paths if data_root is specified
        if self.data_root is not None:
            if not osp.isabs(self.img_dir):
                self.img_dir = osp.join(self.data_root, self.img_dir)
            if not (self.ann_dir is None or osp.isabs(self.ann_dir)):
                self.ann_dir = osp.join(self.data_root, self.ann_dir)
            if not (self.split is None or osp.isabs(self.split)):
                self.split = osp.join(self.data_root, self.split)
            if not osp.isabs(self.auxiliary_img_dir):
                self.auxiliary_img_dir = osp.join(self.data_root, self.auxiliary_img_dir)


        self.train_metadata = pd.read_csv(
            os.path.join(self.data_root, "flood-training-metadata.csv"), parse_dates=["scene_start"]
        )
        self.train_metadata["feature_path"] = (
                self.img_dir + '/' + self.train_metadata.image_id + '.tif'
        )
        self.train_metadata["auxiliary_dir"] = (
                self.auxiliary_img_dir + '/'
        )
        self.train_metadata["label_path"] = (
                self.ann_dir + '/' + self.train_metadata.chip_id + '.tif'
        )
        
        # __import__("pudb").set_trace()
        self.train_x = get_paths_by_chip(self.train_metadata, self.auxiliary_img_suffixes)
        self.train_y = self.train_metadata[["chip_id", "label_path"]].drop_duplicates().reset_index(drop=True)

        # load annotations
        self.img_infos = self.load_annotations(self.train_x, self.train_y)

    def __len__(self):
        """Total number of samples of data."""
        return len(self.img_infos)

    def load_annotations(self, image_infos, label_infos):
        """Load annotation from directory.

        Args:
            img_dir (str): Path to image directory
            ann_dir (str|None): Path to annotation directory.
        Returns:
            list[dict]: All image info of dataset.
        """

        img_infos = []

        for i in range(len(image_infos)):
            img_info = dict(filename_vv=os.path.basename(image_infos.iloc[i].vv_path),
                            filename_vh=os.path.basename(image_infos.iloc[i].vh_path),
                            jrc_gsw_change=os.path.basename(image_infos.iloc[i].jrc_gsw_change),
                            jrc_gsw_transitions=os.path.basename(image_infos.iloc[i].jrc_gsw_transitions),
                            jrc_gsw_seasonality=os.path.basename(image_infos.iloc[i].jrc_gsw_seasonality),
                            jrc_gsw_recurrence=os.path.basename(image_infos.iloc[i].jrc_gsw_recurrence),
                            jrc_gsw_occurrence=os.path.basename(image_infos.iloc[i].jrc_gsw_occurrence),
                            jrc_gsw_extent=os.path.basename(image_infos.iloc[i].jrc_gsw_extent),
                            nasadem=os.path.basename(image_infos.iloc[i].nasadem),
                            )

            seg_map = os.path.basename(label_infos.iloc[i].label_path)
            img_info['ann'] = dict(seg_map=seg_map)
            img_infos.append(img_info)

        print_log(f'Loaded {len(img_infos)} images', logger=get_root_logger())
        return img_infos

    def get_ann_info(self, idx):
        """Get annotation by index.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Annotation info of specified index.
        """

        return self.img_infos[idx]['ann']

    def pre_pipeline(self, results):
        """Prepare results dict for pipeline."""
        results['seg_fields'] = []
        results['img_prefix'] = self.img_dir
        results['img_auxiliary'] = self.auxiliary_img_dir
        results['seg_prefix'] = self.ann_dir
        if self.custom_classes:
            results['label_map'] = self.label_map

    def __getitem__(self, idx):
        """Get training/test data after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Training/test data (with annotation if `test_mode` is set
                False).
        """

        if self.test_mode:
            # __import__("pudb").set_trace()
            return self.prepare_test_img(idx)
        else:
            return self.prepare_train_img(idx)

    def prepare_train_img(self, idx):
        """Get training data and annotations after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Training data and annotation after pipeline with new keys
                introduced by pipeline.
        """

        img_info = self.img_infos[idx]
        ann_info = self.get_ann_info(idx)
        results = dict(img_info=img_info, ann_info=ann_info)
        self.pre_pipeline(results)
        return self.pipeline(results)

    def prepare_test_img(self, idx):
        """Get testing data after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Testing data after pipeline with new keys introduced by
                pipeline.
        """

        img_info = self.img_infos[idx]
        results = dict(img_info=img_info)
        self.pre_pipeline(results)
        return self.pipeline(results)

    def format_results(self, results, **kwargs):
        """Place holder to format result to dataset specific output."""

    def get_gt_seg_maps(self, efficient_test=False):
        """Get ground truth segmentation maps for evaluation."""
        gt_seg_maps = []
        for img_info in self.img_infos:
            seg_map = osp.join(self.ann_dir, img_info['ann']['seg_map'])
            if efficient_test:
                gt_seg_map = seg_map
            else:
                gt_seg_map = mmcv.imread(
                    seg_map, flag='unchanged', backend='pillow')
            gt_seg_maps.append(gt_seg_map)
        return gt_seg_maps

    def get_classes_and_palette(self, classes=None, palette=None):
        """Get class names of current dataset.

        Args:
            classes (Sequence[str] | str | None): If classes is None, use
                default CLASSES defined by builtin dataset. If classes is a
                string, take it as a file name. The file contains the name of
                classes where each line contains one class name. If classes is
                a tuple or list, override the CLASSES defined by the dataset.
            palette (Sequence[Sequence[int]]] | np.ndarray | None):
                The palette of segmentation map. If None is given, random
                palette will be generated. Default: None
        """
        if classes is None:
            self.custom_classes = False
            return self.CLASSES, self.PALETTE

        self.custom_classes = True
        if isinstance(classes, str):
            # take it as a file path
            class_names = mmcv.list_from_file(classes)
        elif isinstance(classes, (tuple, list)):
            class_names = classes
        else:
            raise ValueError(f'Unsupported type {type(classes)} of classes.')

        if self.CLASSES:
            if not set(classes).issubset(self.CLASSES):
                raise ValueError('classes is not a subset of CLASSES.')

            # dictionary, its keys are the old label ids and its values
            # are the new label ids.
            # used for changing pixel labels in load_annotations.
            self.label_map = {}
            for i, c in enumerate(self.CLASSES):
                if c not in class_names:
                    self.label_map[i] = -1
                else:
                    self.label_map[i] = classes.index(c)

        palette = self.get_palette_for_custom_classes(class_names, palette)

        return class_names, palette

    def get_palette_for_custom_classes(self, class_names, palette=None):

        if self.label_map is not None:
            # return subset of palette
            palette = []
            for old_id, new_id in sorted(
                    self.label_map.items(), key=lambda x: x[1]):
                if new_id != -1:
                    palette.append(self.PALETTE[old_id])
            palette = type(self.PALETTE)(palette)

        elif palette is None:
            if self.PALETTE is None:
                palette = np.random.randint(0, 255, size=(len(class_names), 3))
            else:
                palette = self.PALETTE

        return palette

    def evaluate(self,
                 results,
                 metric='mIoU',
                 logger=None,
                 efficient_test=False,
                 **kwargs):
        """Evaluate the dataset.

        Args:
            results (list): Testing results of the dataset.
            metric (str | list[str]): Metrics to be evaluated. 'mIoU',
                'mDice' and 'mFscore' are supported.
            logger (logging.Logger | None | str): Logger used for printing
                related information during evaluation. Default: None.

        Returns:
            dict[str, float]: Default metrics.
        """

        if isinstance(metric, str):
            metric = [metric]
        allowed_metrics = ['mIoU', 'mDice', 'mFscore']
        if not set(metric).issubset(set(allowed_metrics)):
            raise KeyError('metric {} is not supported'.format(metric))
        eval_results = {}
        gt_seg_maps = self.get_gt_seg_maps(efficient_test)
        if self.CLASSES is None:
            num_classes = len(
                reduce(np.union1d, [np.unique(_) for _ in gt_seg_maps]))
        else:
            num_classes = len(self.CLASSES)
        ret_metrics = eval_metrics(
            results,
            gt_seg_maps,
            num_classes,
            self.ignore_index,
            metric,
            label_map=self.label_map,
            reduce_zero_label=self.reduce_zero_label)

        if self.CLASSES is None:
            class_names = tuple(range(num_classes))
        else:
            class_names = self.CLASSES

        # summary table
        ret_metrics_summary = OrderedDict({
            ret_metric: np.round(np.nanmean(ret_metric_value) * 100, 2)
            for ret_metric, ret_metric_value in ret_metrics.items()
        })

        # each class table
        ret_metrics.pop('aAcc', None)
        ret_metrics_class = OrderedDict({
            ret_metric: np.round(ret_metric_value * 100, 2)
            for ret_metric, ret_metric_value in ret_metrics.items()
        })
        ret_metrics_class.update({'Class': class_names})
        ret_metrics_class.move_to_end('Class', last=False)

        # for logger
        class_table_data = PrettyTable()
        for key, val in ret_metrics_class.items():
            class_table_data.add_column(key, val)

        summary_table_data = PrettyTable()
        for key, val in ret_metrics_summary.items():
            if key == 'aAcc':
                summary_table_data.add_column(key, [val])
            else:
                summary_table_data.add_column('m' + key, [val])

        print_log('per class results:', logger)
        print_log('\n' + class_table_data.get_string(), logger=logger)
        print_log('Summary:', logger)
        print_log('\n' + summary_table_data.get_string(), logger=logger)

        # each metric dict
        for key, value in ret_metrics_summary.items():
            if key == 'aAcc':
                eval_results[key] = value / 100.0
            else:
                eval_results['m' + key] = value / 100.0

        ret_metrics_class.pop('Class', None)
        for key, value in ret_metrics_class.items():
            eval_results.update({
                key + '.' + str(name): value[idx] / 100.0
                for idx, name in enumerate(class_names)
            })

        if mmcv.is_list_of(results, str):
            for file_name in results:
                os.remove(file_name)
        return eval_results

import os
import os.path as osp
from collections import OrderedDict
from functools import reduce
import pandas as pd
import mmcv
import numpy as np
from mmcv.utils import print_log
from prettytable import PrettyTable
from torch.utils.data import Dataset

from mmseg.core import eval_metrics
from mmseg.utils import get_root_logger
from .builder import DATASETS
from .pipelines import Compose

def get_paths_by_chip(image_level_df, auxiliary_img_suffixes):
    """
    Returns a chip-level dataframe with pivoted columns
    for vv_path and vh_path.

    Args:
        image_level_df (pd.DataFrame): image-level dataframe

    Returns:
        chip_level_df (pd.DataFrame): chip-level dataframe
    """
    paths = []

    for chip, group in image_level_df.groupby("chip_id"):
        vv_path = group[group.polarization == "vv"]["feature_path"].values[0]
        vh_path = group[group.polarization == "vh"]["feature_path"].values[0]
        auxiliary_paths = []

        for suffix in auxiliary_img_suffixes:
            auxiliary_paths.append(os.path.join(group["auxiliary_dir"].values[0], chip + suffix + '.tif'))
        paths.append([chip, vv_path, vh_path] + auxiliary_paths)

    columns_name = ["chip_id", "vv_path", "vh_path"]
    for suffix in auxiliary_img_suffixes: columns_name.append(suffix[1:].replace('-', '_'))
    return pd.DataFrame(paths, columns=columns_name)


@DATASETS.register_module()
class FloodDataSet(Dataset):

    CLASSES = None

    PALETTE = None

    def __init__(self,
                 pipeline,
                 img_dir,
                 auxiliary_img_dir=None,
                 auxiliary_img_suffixes=['_jrc-gsw-change', '_jrc-gsw-transitions', '_jrc-gsw-seasonality', \
                                         '_jrc-gsw-recurrence', '_jrc-gsw-occurrence',  '_jrc-gsw-extent', '_nasadem'],
                 ann_dir=None,
                 split=None,
                 data_root=None,
                 test_mode=False,
                 ignore_index=255,
                 reduce_zero_label=False,
                 classes=None,
                 palette=None):
        self.pipeline = Compose(pipeline)
        self.img_dir = img_dir
        self.auxiliary_img_dir = auxiliary_img_dir
        self.auxiliary_img_suffixes = auxiliary_img_suffixes
        self.ann_dir = ann_dir
        self.split = split
        self.data_root = data_root
        self.test_mode = test_mode
        self.ignore_index = ignore_index
        self.reduce_zero_label = reduce_zero_label
        self.label_map = None
        self.CLASSES, self.PALETTE = self.get_classes_and_palette(
            classes, palette)


        # join paths if data_root is specified
        if self.data_root is not None:
            if not osp.isabs(self.img_dir):
                self.img_dir = osp.join(self.data_root, self.img_dir)
            if not (self.ann_dir is None or osp.isabs(self.ann_dir)):
                self.ann_dir = osp.join(self.data_root, self.ann_dir)
            if not (self.split is None or osp.isabs(self.split)):
                self.split = osp.join(self.data_root, self.split)
            if not osp.isabs(self.auxiliary_img_dir):
                self.auxiliary_img_dir = osp.join(self.data_root, self.auxiliary_img_dir)


        self.train_metadata = pd.read_csv(
            os.path.join(self.data_root, "flood-training-metadata.csv"), parse_dates=["scene_start"]
        )
        self.train_metadata["feature_path"] = (
                self.img_dir + '/' + self.train_metadata.image_id + '.tif'
        )
        self.train_metadata["auxiliary_dir"] = (
                self.auxiliary_img_dir + '/'
        )
        self.train_metadata["label_path"] = (
                self.ann_dir + '/' + self.train_metadata.chip_id + '.tif'
        )
        
        # __import__("pudb").set_trace()
        self.train_x = get_paths_by_chip(self.train_metadata, self.auxiliary_img_suffixes)
        self.train_y = self.train_metadata[["chip_id", "label_path"]].drop_duplicates().reset_index(drop=True)

        # load annotations
        self.img_infos = self.load_annotations(self.train_x, self.train_y)

    def __len__(self):
        """Total number of samples of data."""
        return len(self.img_infos)

    def load_annotations(self, image_infos, label_infos):
        """Load annotation from directory.

        Args:
            img_dir (str): Path to image directory
            ann_dir (str|None): Path to annotation directory.
        Returns:
            list[dict]: All image info of dataset.
        """

        img_infos = []

        for i in range(len(image_infos)):
            img_info = dict(filename_vv=os.path.basename(image_infos.iloc[i].vv_path),
                            filename_vh=os.path.basename(image_infos.iloc[i].vh_path),
                            jrc_gsw_change=os.path.basename(image_infos.iloc[i].jrc_gsw_change),
                            jrc_gsw_transitions=os.path.basename(image_infos.iloc[i].jrc_gsw_transitions),
                            jrc_gsw_seasonality=os.path.basename(image_infos.iloc[i].jrc_gsw_seasonality),
                            jrc_gsw_recurrence=os.path.basename(image_infos.iloc[i].jrc_gsw_recurrence),
                            jrc_gsw_occurrence=os.path.basename(image_infos.iloc[i].jrc_gsw_occurrence),
                            jrc_gsw_extent=os.path.basename(image_infos.iloc[i].jrc_gsw_extent),
                            nasadem=os.path.basename(image_infos.iloc[i].nasadem),
                            )

            seg_map = os.path.basename(label_infos.iloc[i].label_path)
            img_info['ann'] = dict(seg_map=seg_map)
            img_infos.append(img_info)

        print_log(f'Loaded {len(img_infos)} images', logger=get_root_logger())
        return img_infos

    def get_ann_info(self, idx):
        """Get annotation by index.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Annotation info of specified index.
        """

        return self.img_infos[idx]['ann']

    def pre_pipeline(self, results):
        """Prepare results dict for pipeline."""
        results['seg_fields'] = []
        results['img_prefix'] = self.img_dir
        results['img_auxiliary'] = self.auxiliary_img_dir
        results['seg_prefix'] = self.ann_dir
        if self.custom_classes:
            results['label_map'] = self.label_map

    def __getitem__(self, idx):
        """Get training/test data after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Training/test data (with annotation if `test_mode` is set
                False).
        """

        if self.test_mode:
            # __import__("pudb").set_trace()
            return self.prepare_test_img(idx)
        else:
            return self.prepare_train_img(idx)

    def prepare_train_img(self, idx):
        """Get training data and annotations after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Training data and annotation after pipeline with new keys
                introduced by pipeline.
        """

        img_info = self.img_infos[idx]
        ann_info = self.get_ann_info(idx)
        results = dict(img_info=img_info, ann_info=ann_info)
        self.pre_pipeline(results)
        return self.pipeline(results)

    def prepare_test_img(self, idx):
        """Get testing data after pipeline.

        Args:
            idx (int): Index of data.

        Returns:
            dict: Testing data after pipeline with new keys introduced by
                pipeline.
        """

        img_info = self.img_infos[idx]
        results = dict(img_info=img_info)
        self.pre_pipeline(results)
        return self.pipeline(results)

    def format_results(self, results, **kwargs):
        """Place holder to format result to dataset specific output."""

    def get_gt_seg_maps(self, efficient_test=False):
        """Get ground truth segmentation maps for evaluation."""
        gt_seg_maps = []
        for img_info in self.img_infos:
            seg_map = osp.join(self.ann_dir, img_info['ann']['seg_map'])
            if efficient_test:
                gt_seg_map = seg_map
            else:
                gt_seg_map = mmcv.imread(
                    seg_map, flag='unchanged', backend='pillow')
            gt_seg_maps.append(gt_seg_map)
        return gt_seg_maps

    def get_classes_and_palette(self, classes=None, palette=None):
        """Get class names of current dataset.

        Args:
            classes (Sequence[str] | str | None): If classes is None, use
                default CLASSES defined by builtin dataset. If classes is a
                string, take it as a file name. The file contains the name of
                classes where each line contains one class name. If classes is
                a tuple or list, override the CLASSES defined by the dataset.
            palette (Sequence[Sequence[int]]] | np.ndarray | None):
                The palette of segmentation map. If None is given, random
                palette will be generated. Default: None
        """
        if classes is None:
            self.custom_classes = False
            return self.CLASSES, self.PALETTE

        self.custom_classes = True
        if isinstance(classes, str):
            # take it as a file path
            class_names = mmcv.list_from_file(classes)
        elif isinstance(classes, (tuple, list)):
            class_names = classes
        else:
            raise ValueError(f'Unsupported type {type(classes)} of classes.')

        if self.CLASSES:
            if not set(classes).issubset(self.CLASSES):
                raise ValueError('classes is not a subset of CLASSES.')

            # dictionary, its keys are the old label ids and its values
            # are the new label ids.
            # used for changing pixel labels in load_annotations.
            self.label_map = {}
            for i, c in enumerate(self.CLASSES):
                if c not in class_names:
                    self.label_map[i] = -1
                else:
                    self.label_map[i] = classes.index(c)

        palette = self.get_palette_for_custom_classes(class_names, palette)

        return class_names, palette

    def get_palette_for_custom_classes(self, class_names, palette=None):

        if self.label_map is not None:
            # return subset of palette
            palette = []
            for old_id, new_id in sorted(
                    self.label_map.items(), key=lambda x: x[1]):
                if new_id != -1:
                    palette.append(self.PALETTE[old_id])
            palette = type(self.PALETTE)(palette)

        elif palette is None:
            if self.PALETTE is None:
                palette = np.random.randint(0, 255, size=(len(class_names), 3))
            else:
                palette = self.PALETTE

        return palette

    def evaluate(self,
                 results,
                 metric='mIoU',
                 logger=None,
                 efficient_test=False,
                 **kwargs):
        """Evaluate the dataset.

        Args:
            results (list): Testing results of the dataset.
            metric (str | list[str]): Metrics to be evaluated. 'mIoU',
                'mDice' and 'mFscore' are supported.
            logger (logging.Logger | None | str): Logger used for printing
                related information during evaluation. Default: None.

        Returns:
            dict[str, float]: Default metrics.
        """

        if isinstance(metric, str):
            metric = [metric]
        allowed_metrics = ['mIoU', 'mDice', 'mFscore']
        if not set(metric).issubset(set(allowed_metrics)):
            raise KeyError('metric {} is not supported'.format(metric))
        eval_results = {}
        gt_seg_maps = self.get_gt_seg_maps(efficient_test)
        if self.CLASSES is None:
            num_classes = len(
                reduce(np.union1d, [np.unique(_) for _ in gt_seg_maps]))
        else:
            num_classes = len(self.CLASSES)
        ret_metrics = eval_metrics(
            results,
            gt_seg_maps,
            num_classes,
            self.ignore_index,
            metric,
            label_map=self.label_map,
            reduce_zero_label=self.reduce_zero_label)

        if self.CLASSES is None:
            class_names = tuple(range(num_classes))
        else:
            class_names = self.CLASSES

        # summary table
        ret_metrics_summary = OrderedDict({
            ret_metric: np.round(np.nanmean(ret_metric_value) * 100, 2)
            for ret_metric, ret_metric_value in ret_metrics.items()
        })

        # each class table
        ret_metrics.pop('aAcc', None)
        ret_metrics_class = OrderedDict({
            ret_metric: np.round(ret_metric_value * 100, 2)
            for ret_metric, ret_metric_value in ret_metrics.items()
        })
        ret_metrics_class.update({'Class': class_names})
        ret_metrics_class.move_to_end('Class', last=False)

        # for logger
        class_table_data = PrettyTable()
        for key, val in ret_metrics_class.items():
            class_table_data.add_column(key, val)

        summary_table_data = PrettyTable()
        for key, val in ret_metrics_summary.items():
            if key == 'aAcc':
                summary_table_data.add_column(key, [val])
            else:
                summary_table_data.add_column('m' + key, [val])

        print_log('per class results:', logger)
        print_log('\n' + class_table_data.get_string(), logger=logger)
        print_log('Summary:', logger)
        print_log('\n' + summary_table_data.get_string(), logger=logger)

        # each metric dict
        for key, value in ret_metrics_summary.items():
            if key == 'aAcc':
                eval_results[key] = value / 100.0
            else:
                eval_results['m' + key] = value / 100.0

        ret_metrics_class.pop('Class', None)
        for key, value in ret_metrics_class.items():
            eval_results.update({
                key + '.' + str(name): value[idx] / 100.0
                for idx, name in enumerate(class_names)
            })

        if mmcv.is_list_of(results, str):
            for file_name in results:
                os.remove(file_name)
        return eval_results

Returns a chip-level dataframe with pivoted columns
     for vv_path and vh_path.
 
     Args:
         image_level_df (pd.DataFrame): image-level dataframe
 
     Returns:
         chip_level_df (pd.DataFrame): chip-level dataframe # join paths if data_root is specified # __import__("pudb").set_trace() # load annotations Total number of samples of data. Load annotation from directory.
 
         Args:
             img_dir (str): Path to image directory
             ann_dir (str|None): Path to annotation directory.
         Returns:
             list[dict]: All image info of dataset. Get annotation by index.
 
         Args:
             idx (int): Index of data.
 
         Returns:
             dict: Annotation info of specified index. Prepare results dict for pipeline. Get training/test data after pipeline.
 
         Args:
             idx (int): Index of data.
 
         Returns:
             dict: Training/test data (with annotation if `test_mode` is set
                 False). # __import__("pudb").set_trace() Get training data and annotations after pipeline.
 
         Args:
             idx (int): Index of data.
 
         Returns:
             dict: Training data and annotation after pipeline with new keys
                 introduced by pipeline. Get testing data after pipeline.
 
         Args:
             idx (int): Index of data.
 
         Returns:
             dict: Testing data after pipeline with new keys introduced by
                 pipeline. Place holder to format result to dataset specific output. Get ground truth segmentation maps for evaluation. Get class names of current dataset.
 
         Args:
             classes (Sequence[str] | str | None): If classes is None, use
                 default CLASSES defined by builtin dataset. If classes is a
                 string, take it as a file name. The file contains the name of
                 classes where each line contains one class name. If classes is
                 a tuple or list, override the CLASSES defined by the dataset.
             palette (Sequence[Sequence[int]]] | np.ndarray | None):
                 The palette of segmentation map. If None is given, random
                 palette will be generated. Default: None # take it as a file path # dictionary, its keys are the old label ids and its values # are the new label ids. # used for changing pixel labels in load_annotations. # return subset of palette Evaluate the dataset.
 
         Args:
             results (list): Testing results of the dataset.
             metric (str | list[str]): Metrics to be evaluated. 'mIoU',
                 'mDice' and 'mFscore' are supported.
             logger (logging.Logger | None | str): Logger used for printing
                 related information during evaluation. Default: None.
 
         Returns:
             dict[str, float]: Default metrics. # summary table # each class table # for logger # each metric dict