# mir_eval.chord

Chord estimation algorithms produce a list of intervals and labels which denote the chord being played over each timespan. They are evaluated by comparing the estimated chord labels to some reference, usually using a mapping to a chord subalphabet (e.g. minor and major chords only, all triads, etc.). There is no single ‘right’ way to compare two sequences of chord labels. Embracing this reality, every conventional comparison rule is provided. Comparisons are made over the different components of each chord (e.g. G:maj(6)/5): the root (G), the root-invariant active semitones as determined by the quality shorthand (maj) and scale degrees (6), and the bass interval (5). This submodule provides functions both for comparing a sequences of chord labels according to some chord subalphabet mapping and for using these comparisons to score a sequence of estimated chords against a reference.

## Conventions

A sequence of chord labels is represented as a list of strings, where each label is the chord name based on the syntax of [1]. Reference and estimated chord label sequences should be of the same length for comparison functions. When converting the chord string into its constituent parts,

- Pitch class counting starts at C, e.g. C:0, D:2, E:4, F:5, etc.

- Scale degree is represented as a string of the diatonic interval, relative to the root note, e.g. ‘b6’, ‘#5’, or ‘7’

- Bass intervals are represented as strings

- Chord bitmaps are positional binary vectors indicating active pitch classes and may be absolute or relative depending on context in the code.

If no chord is present at a given point in time, it should have the label ‘N’, which is defined in the variable `mir_eval.chord.NO_CHORD`.

## Metrics

- `mir_eval.chord.root()`: Only compares the root of the chords.

- `mir_eval.chord.majmin()`: Only compares major, minor, and “no chord” labels.

- `mir_eval.chord.majmin_inv()`: Compares major/minor chords, with inversions. The bass note must exist in the triad.

- `mir_eval.chord.mirex()`: A estimated chord is considered correct if it shares at least three pitch classes in common.

- `mir_eval.chord.thirds()`: Chords are compared at the level of major or minor thirds (root and third), For example, both (‘A:7’, ‘A:maj’) and (‘A:min’, ‘A:dim’) are equivalent, as the third is major and minor in quality, respectively.

- `mir_eval.chord.thirds_inv()`: Same as above, with inversions (bass relationships).

- `mir_eval.chord.triads()`: Chords are considered at the level of triads (major, minor, augmented, diminished, suspended), meaning that, in addition to the root, the quality is only considered through #5th scale degree (for augmented chords). For example, (‘A:7’, ‘A:maj’) are equivalent, while (‘A:min’, ‘A:dim’) and (‘A:aug’, ‘A:maj’) are not.

- `mir_eval.chord.triads_inv()`: Same as above, with inversions (bass relationships).

- `mir_eval.chord.tetrads()`: Chords are considered at the level of the entire quality in closed voicing, i.e. spanning only a single octave; extended chords (9’s, 11’s and 13’s) are rolled into a single octave with any upper voices included as extensions. For example, (‘A:7’, ‘A:9’) are equivalent but (‘A:7’, ‘A:maj7’) are not.

- `mir_eval.chord.tetrads_inv()`: Same as above, with inversions (bass relationships).

- `mir_eval.chord.sevenths()`: Compares according to MIREX “sevenths” rules; that is, only major, major seventh, seventh, minor, minor seventh and no chord labels are compared.

- `mir_eval.chord.sevenths_inv()`: Same as above, with inversions (bass relationships).

- `mir_eval.chord.overseg()`: Computes the level of over-segmentation between estimated and reference intervals.

- `mir_eval.chord.underseg()`: Computes the level of under-segmentation between estimated and reference intervals.

- `mir_eval.chord.seg()`: Computes the minimum of over- and under-segmentation between estimated and reference intervals.

## References

> [1] (1,2)

> C. Harte. Towards Automatic Extraction of Harmony Information from Music Signals. PhD thesis, Queen Mary University of London, August 2010.

exception mir_eval.chord.InvalidChordException(message='', chord_label=None)

  Bases: `Exception`

  Exception class for suspect / invalid chord labels

mir_eval.chord.pitch_class_to_semitone(pitch_class)

  Convert a pitch class to semitone.

  Parameters:
    pitch_class str

      Spelling of a given pitch class, e.g. ‘C#’, ‘Gbb’

  Returns:
    semitone int

      Semitone value of the pitch class.

mir_eval.chord.scale_degree_to_semitone(scale_degree)

  Convert a scale degree to semitone.

  Parameters:
    scale_degree str

      Spelling of a relative scale degree, e.g. ‘b3’, ‘7’, ‘#5’

  Returns:
    semitone int

      Relative semitone of the scale degree, wrapped to a single octave

  Raises:
    InvalidChordException if scale_degree is invalid.

mir_eval.chord.scale_degree_to_bitmap(scale_degree, modulo=False, length=12)

  Create a bitmap representation of a scale degree.

  Note that values in the bitmap may be negative, indicating that the semitone is to be removed.

  Parameters:
    scale_degree str

      Spelling of a relative scale degree, e.g. ‘b3’, ‘7’, ‘#5’

    modulo bool, default=True

      If a scale degree exceeds the length of the bit-vector, modulo the scale degree back into the bit-vector; otherwise it is discarded.

    length int, default=12

      Length of the bit-vector to produce

  Returns:
    bitmap np.ndarray, in [-1, 0, 1], len=`length`

      Bitmap representation of this scale degree.

mir_eval.chord.quality_to_bitmap(quality)

  Return the bitmap for a given quality.

  Parameters:
    quality str

      Chord quality name.

  Returns:
    bitmap np.ndarray

      Bitmap representation of this quality (12-dim).

mir_eval.chord.reduce_extended_quality(quality)

  Map an extended chord quality to a simpler one, moving upper voices to a set of scale degree extensions.

  Parameters:
    quality str

      Extended chord quality to reduce.

  Returns:
    base_quality str

      New chord quality.

    extensions set

      Scale degrees extensions for the quality.

mir_eval.chord.validate_chord_label(chord_label)

  Test for well-formedness of a chord label.

  Parameters:
    chord_label str

      Chord label to validate.

mir_eval.chord.split(chord_label, reduce_extended_chords=False)
  Parse a chord label into its four constituent parts:

    - root

    - quality shorthand

    - scale degrees

    - bass

  Note: Chords lacking quality AND interval information are major.

    - If a quality is specified, it is returned.

    - If an interval is specified WITHOUT a quality, the quality field is empty.

  Some examples:

      'C' -> ['C', 'maj', {}, '1']
      'G#:min(*b3,*5)/5' -> ['G#', 'min', {'*b3', '*5'}, '5']
      'A:(3)/6' -> ['A', '', {'3'}, '6']

  Parameters:
    chord_label str

      A chord label.

    reduce_extended_chords bool

      Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

  Returns:
    chord_parts list

      Split version of the chord label.

mir_eval.chord.join(chord_root, quality='', extensions=None, bass='')

  Join the parts of a chord into a complete chord label.

  Parameters:
    chord_root str

      Root pitch class of the chord, e.g. ‘C’, ‘Eb’

    quality str

      Quality of the chord, e.g. ‘maj’, ‘hdim7’ (Default value = ‘’)

    extensions list

      Any added or absent scaled degrees for this chord, e.g. [‘4’, ‘*3’] (Default value = None)

    bass str

      Scale degree of the bass note, e.g. ‘5’. (Default value = ‘’)

  Returns:
    chord_label str

      A complete chord label.

mir_eval.chord.encode(chord_label, reduce_extended_chords=False, strict_bass_intervals=False)

  Translate a chord label to numerical representations for evaluation.

  Parameters:
    chord_label str

      Chord label to encode.

    reduce_extended_chords bool

      Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

    strict_bass_intervals bool

      Whether to require that the bass scale degree is present in the chord. (Default value = False)

  Returns:
    root_number int

      Absolute semitone of the chord’s root.

    semitone_bitmap np.ndarray, dtype=int

      12-dim vector of relative semitones in the chord spelling.

    bass_number int

      Relative semitone of the chord’s bass note, e.g. 0=root, 7=fifth, etc.

mir_eval.chord.encode_many(chord_labels, reduce_extended_chords=False)

  Translate a set of chord labels to numerical representations for sane evaluation.

  Parameters:
    chord_labels list

      Set of chord labels to encode.

    reduce_extended_chords bool

      Whether to map the upper voicings of extended chords (9’s, 11’s, 13’s) to semitone extensions. (Default value = False)

  Returns:
    root_number np.ndarray, dtype=int

      Absolute semitone of the chord’s root.

    interval_bitmap np.ndarray, dtype=int

      12-dim vector of relative semitones in the given chord quality.

    bass_number np.ndarray, dtype=int

      Relative semitones of the chord’s bass notes.

mir_eval.chord.rotate_bitmap_to_root(bitmap, chord_root)

  Circularly shift a relative bitmap to its absolute pitch classes.

  For clarity, the best explanation is an example. Given ‘G:Maj’, the root and quality map are as follows:

      root=5
      quality=[1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]  # Relative chord shape

  After rotating to the root, the resulting bitmap becomes:

      abs_quality = [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1]  # G, B, and D

  Parameters:
    bitmap np.ndarray, shape=(12,)

      Bitmap of active notes, relative to the given root.

    chord_root int

      Absolute pitch class number.

  Returns:
    bitmap np.ndarray, shape=(12,)

      Absolute bitmap of active pitch classes.

mir_eval.chord.rotate_bitmaps_to_roots(bitmaps, roots)

  Circularly shift a relative bitmaps to absolute pitch classes.

  See `rotate_bitmap_to_root()` for more information.

  Parameters:
    bitmaps np.ndarray, shape=(N, 12)

      Bitmap of active notes, relative to the given root.

    roots np.ndarray, shape=(N,)

      Absolute pitch class number.

  Returns:
    bitmap np.ndarray, shape=(N, 12)

      Absolute bitmaps of active pitch classes.

mir_eval.chord.validate(reference_labels, estimated_labels)

  Check that the input annotations to a comparison function look like valid chord labels.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

mir_eval.chord.weighted_accuracy(comparisons, weights)

  Compute the weighted accuracy of a list of chord comparisons.

  Parameters:
    comparisons np.ndarray

      List of chord comparison scores, in [0, 1] or -1

    weights np.ndarray

      Weights (not necessarily normalized) for each comparison. This can be a list of interval durations

  Returns:
    score float

      Weighted accuracy

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> # Here, we're using the "thirds" function to compare labels
      >>> # but any of the comparison functions would work.
      >>> comparisons = mir_eval.chord.thirds(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.thirds(reference_labels, estimated_labels)

  Compare chords along root & third relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.thirds(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.thirds_inv(reference_labels, estimated_labels)

  Score chords along root, third, & bass relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.thirds_inv(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.triads(reference_labels, estimated_labels)

  Compare chords along triad (root & quality to #5) relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.triads(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.triads_inv(reference_labels, estimated_labels)

  Score chords along triad (root, quality to #5, & bass) relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.triads_inv(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.tetrads(reference_labels, estimated_labels)

  Compare chords along tetrad (root & full quality) relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.tetrads(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.tetrads_inv(reference_labels, estimated_labels)

  Compare chords along tetrad (root, full quality, & bass) relationships.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.tetrads_inv(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.root(reference_labels, estimated_labels)

  Compare chords according to roots.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.root(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.mirex(reference_labels, estimated_labels)

  Compare chords along MIREX rules.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0]

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.mirex(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.majmin(reference_labels, estimated_labels)

  Compare chords along major-minor rules. Chords with qualities outside Major/minor/no-chord are ignored.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.majmin(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.majmin_inv(reference_labels, estimated_labels)

  Compare chords along major-minor rules, with inversions. Chords with qualities outside Major/minor/no-chord are ignored, and the bass note must exist in the triad (bass in [1, 3, 5]).

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.majmin_inv(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.sevenths(reference_labels, estimated_labels)

  Compare chords along MIREX ‘sevenths’ rules. Chords with qualities outside [maj, maj7, 7, min, min7, N] are ignored.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.sevenths(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.sevenths_inv(reference_labels, estimated_labels)

  Compare chords along MIREX ‘sevenths’ rules. Chords with qualities outside [maj, maj7, 7, min, min7, N] are ignored.

  Parameters:
    reference_labels list, len=n

      Reference chord labels to score against.

    estimated_labels list, len=n

      Estimated chord labels to score against.

  Returns:
    comparison_scores np.ndarray, shape=(n,), dtype=float

      Comparison scores, in [0.0, 1.0], or -1 if the comparison is out of gamut.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> est_intervals, est_labels = mir_eval.util.adjust_intervals(
      ...     est_intervals, est_labels, ref_intervals.min(),
      ...     ref_intervals.max(), mir_eval.chord.NO_CHORD,
      ...     mir_eval.chord.NO_CHORD)
      >>> (intervals,
      ...  ref_labels,
      ...  est_labels) = mir_eval.util.merge_labeled_intervals(
      ...      ref_intervals, ref_labels, est_intervals, est_labels)
      >>> durations = mir_eval.util.intervals_to_durations(intervals)
      >>> comparisons = mir_eval.chord.sevenths_inv(ref_labels, est_labels)
      >>> score = mir_eval.chord.weighted_accuracy(comparisons, durations)

mir_eval.chord.directional_hamming_distance(reference_intervals, estimated_intervals)

  Compute the directional hamming distance between reference and estimated intervals as defined by [1] and used for MIREX ‘OverSeg’, ‘UnderSeg’ and ‘MeanSeg’ measures.

  Parameters:
    reference_intervals np.ndarray, shape=(n, 2), dtype=float

      Reference chord intervals to score against.

    estimated_intervals np.ndarray, shape=(m, 2), dtype=float

      Estimated chord intervals to score against.

  Returns:
    directional hamming distance float

      directional hamming distance between reference intervals and estimated intervals.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> overseg = 1 - mir_eval.chord.directional_hamming_distance(
      ...     ref_intervals, est_intervals)
      >>> underseg = 1 - mir_eval.chord.directional_hamming_distance(
      ...     est_intervals, ref_intervals)
      >>> seg = min(overseg, underseg)

mir_eval.chord.overseg(reference_intervals, estimated_intervals)

  Compute the MIREX ‘OverSeg’ score.

  Parameters:
    reference_intervals np.ndarray, shape=(n, 2), dtype=float

      Reference chord intervals to score against.

    estimated_intervals np.ndarray, shape=(m, 2), dtype=float

      Estimated chord intervals to score against.

  Returns:
    oversegmentation score float

      Comparison score, in [0.0, 1.0], where 1.0 means no oversegmentation.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> score = mir_eval.chord.overseg(ref_intervals, est_intervals)

mir_eval.chord.underseg(reference_intervals, estimated_intervals)

  Compute the MIREX ‘UnderSeg’ score.

  Parameters:
    reference_intervals np.ndarray, shape=(n, 2), dtype=float

      Reference chord intervals to score against.

    estimated_intervals np.ndarray, shape=(m, 2), dtype=float

      Estimated chord intervals to score against.

  Returns:
    undersegmentation score float

      Comparison score, in [0.0, 1.0], where 1.0 means no undersegmentation.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> score = mir_eval.chord.underseg(ref_intervals, est_intervals)

mir_eval.chord.seg(reference_intervals, estimated_intervals)

  Compute the MIREX ‘MeanSeg’ score.

  Parameters:
    reference_intervals np.ndarray, shape=(n, 2), dtype=float

      Reference chord intervals to score against.

    estimated_intervals np.ndarray, shape=(m, 2), dtype=float

      Estimated chord intervals to score against.

  Returns:
    segmentation score float

      Comparison score, in [0.0, 1.0], where 1.0 means perfect segmentation.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> score = mir_eval.chord.seg(ref_intervals, est_intervals)

mir_eval.chord.merge_chord_intervals(intervals, labels)

  Merge consecutive chord intervals if they represent the same chord.

  Parameters:
    intervals np.ndarray, shape=(n, 2), dtype=float

      Chord intervals to be merged, in the format returned by `mir_eval.io.load_labeled_intervals()`.

    labels list, shape=(n,)

      Chord labels to be merged, in the format returned by `mir_eval.io.load_labeled_intervals()`.

  Returns:
    merged_ivs np.ndarray, shape=(k, 2), dtype=float

      Merged chord intervals, k <= n

mir_eval.chord.evaluate(ref_intervals, ref_labels, est_intervals, est_labels, **kwargs)

  Compute weighted accuracy for all comparison functions for the given reference and estimated annotations.

  Parameters:
    ref_intervals np.ndarray, shape=(n, 2)

      Reference chord intervals, in the format returned by `mir_eval.io.load_labeled_intervals()`.

    ref_labels list, shape=(n,)

      reference chord labels, in the format returned by `mir_eval.io.load_labeled_intervals()`.

    est_intervals np.ndarray, shape=(m, 2)

      estimated chord intervals, in the format returned by `mir_eval.io.load_labeled_intervals()`.

    est_labels list, shape=(m,)

      estimated chord labels, in the format returned by `mir_eval.io.load_labeled_intervals()`.

    **kwargs

      Additional keyword arguments which will be passed to the appropriate metric or preprocessing functions.

  Returns:
    scores dict

      Dictionary of scores, where the key is the metric name (str) and the value is the (float) score achieved.

  Examples

      >>> (ref_intervals,
      ...  ref_labels) = mir_eval.io.load_labeled_intervals('ref.lab')
      >>> (est_intervals,
      ...  est_labels) = mir_eval.io.load_labeled_intervals('est.lab')
      >>> scores = mir_eval.chord.evaluate(ref_intervals, ref_labels,
      ...                                  est_intervals, est_labels)