# Path: dsegmenter/evaluation/segmentation.py
# def get_untyped_masses(tree):
#     """ Extracts the untyped segmentation masses from a tree.
# 
#     Extracts a segmentation of the leaves of a tree, such that each
#     start or end of a child node triggers a boundary. The segmentation
#     is returned as a list of segments lengths.
# 
#     >>> from nltk.tree import Tree
#     >>> get_untyped_masses(Tree.fromstring('(A x x x)'))
#     [3]
#     >>> get_untyped_masses(Tree.fromstring('(A x (B x (C x)))'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A (B (C x) x) x)'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A (B x) (C x) (D x))'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A x (B x (C x) x) x)'))
#     [1, 1, 1, 1, 1]
#     """
#     return list(m for m, _c in get_typed_masses(tree))
# 
# def get_typed_nonoverlapping_spans(tree):
#     """ Extracts non-overlapping typed spans from a tree.
# 
#     Returns a linearly ordered list of pre-terminal nodes as span
#     tuples (position, length, label).
# 
#     >>> from nltk.tree import Tree
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A x x x)'))
#     ([(0, 3, 'A')], 3)
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A x (B x (C x)))'))
#     ([(0, 1, 'A'), (1, 1, 'B'), (2, 1, 'C')], 3)
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A (B (C x) x) x)'))
#     ([(0, 1, 'C'), (1, 1, 'B'), (2, 1, 'A')], 3)
#     >>> get_typed_nonoverlapping_spans(
#     ...     Tree.fromstring('(A (B x) (C x) (D x))'))
#     ([(0, 1, 'B'), (1, 1, 'C'), (2, 1, 'D')], 3)
#     >>> get_typed_nonoverlapping_spans(
#     ...     Tree.fromstring('(A x (B x (C x) x) x)'))
#     ([(0, 1, 'A'), (1, 1, 'B'), (2, 1, 'C'), (3, 1, 'B'), (4, 1, 'A')], 5)
#     """
#     typed_masses = get_typed_masses(tree)
#     spans = list(typed_masses_to_spans(typed_masses))
#     last_start, last_length, _ = spans[-1]
#     return spans, last_start + last_length


import os
import math
import subprocess
import segeval
import parseval
from itertools import chain
from collections import Counter
from .segmentation import get_untyped_masses, get_typed_nonoverlapping_spans
    """
    assert len(ground_truth) == len(prediction)
    items_count = len(ground_truth)
    accuracy = metric_accuracy(ground_truth, prediction)

    # confusion matrix
    cf = Counter(zip(ground_truth, prediction))
    categories = set(ground_truth) | set(prediction)
    confusions = {gold: {pred: cf.get((gold, pred), 0) for pred in categories}
                  for gold in categories}
    # marginals
    gold_category_distribution = {
        g: sum([confusions[g][p] for p in categories]) for g in categories
    }
    pred_category_distribution = {
        p: sum([confusions[g][p] for g in categories]) for p in categories
    }

    # kappa
    expected_agreement_cohen = sum([
        (float(gold_category_distribution[c]) / items_count) *
        (float(pred_category_distribution[c]) / items_count)
        for c in categories
    ])
    kappa_cohen = (1.0 * (accuracy - expected_agreement_cohen) /
                   (1 - expected_agreement_cohen))
    return kappa_cohen, expected_agreement_cohen, accuracy


def metric_pk(forest1, forest2):

# Path: dsegmenter/evaluation/segmentation.py
# def get_untyped_masses(tree):
#     """ Extracts the untyped segmentation masses from a tree.
# 
#     Extracts a segmentation of the leaves of a tree, such that each
#     start or end of a child node triggers a boundary. The segmentation
#     is returned as a list of segments lengths.
# 
#     >>> from nltk.tree import Tree
#     >>> get_untyped_masses(Tree.fromstring('(A x x x)'))
#     [3]
#     >>> get_untyped_masses(Tree.fromstring('(A x (B x (C x)))'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A (B (C x) x) x)'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A (B x) (C x) (D x))'))
#     [1, 1, 1]
#     >>> get_untyped_masses(Tree.fromstring('(A x (B x (C x) x) x)'))
#     [1, 1, 1, 1, 1]
#     """
#     return list(m for m, _c in get_typed_masses(tree))
# 
# def get_typed_nonoverlapping_spans(tree):
#     """ Extracts non-overlapping typed spans from a tree.
# 
#     Returns a linearly ordered list of pre-terminal nodes as span
#     tuples (position, length, label).
# 
#     >>> from nltk.tree import Tree
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A x x x)'))
#     ([(0, 3, 'A')], 3)
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A x (B x (C x)))'))
#     ([(0, 1, 'A'), (1, 1, 'B'), (2, 1, 'C')], 3)
#     >>> get_typed_nonoverlapping_spans(Tree.fromstring('(A (B (C x) x) x)'))
#     ([(0, 1, 'C'), (1, 1, 'B'), (2, 1, 'A')], 3)
#     >>> get_typed_nonoverlapping_spans(
#     ...     Tree.fromstring('(A (B x) (C x) (D x))'))
#     ([(0, 1, 'B'), (1, 1, 'C'), (2, 1, 'D')], 3)
#     >>> get_typed_nonoverlapping_spans(
#     ...     Tree.fromstring('(A x (B x (C x) x) x)'))
#     ([(0, 1, 'A'), (1, 1, 'B'), (2, 1, 'C'), (3, 1, 'B'), (4, 1, 'A')], 5)
#     """
#     typed_masses = get_typed_masses(tree)
#     spans = list(typed_masses_to_spans(typed_masses))
#     last_start, last_length, _ = spans[-1]
#     return spans, last_start + last_length


# Path: dsegmenter/evaluation/metrics.py
import os
import math
import subprocess
import segeval
import parseval
from itertools import chain
from collections import Counter
from .segmentation import get_untyped_masses, get_typed_nonoverlapping_spans

    """
    assert len(ground_truth) == len(prediction)
    items_count = len(ground_truth)
    accuracy = metric_accuracy(ground_truth, prediction)

    # confusion matrix
    cf = Counter(zip(ground_truth, prediction))
    categories = set(ground_truth) | set(prediction)
    confusions = {gold: {pred: cf.get((gold, pred), 0) for pred in categories}
                  for gold in categories}
    # marginals
    gold_category_distribution = {
        g: sum([confusions[g][p] for p in categories]) for g in categories
    }
    pred_category_distribution = {
        p: sum([confusions[g][p] for g in categories]) for p in categories
    }

    # kappa
    expected_agreement_cohen = sum([
        (float(gold_category_distribution[c]) / items_count) *
        (float(pred_category_distribution[c]) / items_count)
        for c in categories
    ])
    kappa_cohen = (1.0 * (accuracy - expected_agreement_cohen) /
                   (1 - expected_agreement_cohen))
    return kappa_cohen, expected_agreement_cohen, accuracy


def metric_pk(forest1, forest2):

    masses1 = [get_untyped_masses(tree) for tree in forest1]