o
    si                      @   s  d Z ddlZddlZddlZddlZddlmZ dZdZ	de
dge dfZdZde
dge dfZG dd	 d	eZd
d Zdd Ze Zdd Ze Zdd ZdefddZi dg ddg ddg ddg ddg ddg d d!g d"d#g d$d%g d&d'g d(d)g d*d+g d,d-g d.d/g d0d1g d$d2g d&d3g d"g d&g d"g d$g d&g d"g d4g d5g d6d7Zd8d9 Zdd!hfd#d3hfd%d3hfd!d3hfd!d:hfd!d;hfd!d3d<hfd!d3d=hfd!h d>fd!h d?fd%d3d<hfd#h d>fd%h d>fd@ZdAdB ZedCZdDdE Zd{dFdGZd|dIdJZd}dKdLZ d{dMdNZ!dOdP Z"dQdR Z#dSdT Z$dUdV Z%dWdX Z&dYdZ Z'd[d\ Z(d]d^ Z)d_d` Z*dadb Z+dcdd Z,dedf Z-dgdh Z.didj Z/dkdl Z0dmdn Z1dodp Z2dqdr Z3dsdt Z4dudv Z5dwdx Z6dydz Z7dS )~a  
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 [#harte2010towards]_.  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
-------

* :func:`mir_eval.chord.root`: Only compares the root of the chords.

* :func:`mir_eval.chord.majmin`: Only compares major, minor, and "no chord"
  labels.

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

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

* :func:`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.

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

* :func:`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.

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

* :func:`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.

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

* :func:`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.

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

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

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

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

References
----------
    .. [#harte2010towards] C. Harte. Towards Automatic Extraction of Harmony
        Information from Music Signals. PhD thesis, Queen Mary University of
        London, August 2010.
    N)util   NXc                       s"   e Zd ZdZd fdd	Z  ZS )InvalidChordExceptionz2Exception class for suspect / invalid chord labels Nc                    s&   || _ || _| jj| _t | d S )N)messagechord_label	__class____name__namesuper__init__)selfr	   r
   r    B/home/ubuntu/.local/lib/python3.10/site-packages/mir_eval/chord.pyr   t   s   
zInvalidChordException.__init__)r   N)r   
__module____qualname____doc__r   __classcell__r   r   r   r   r   q   s    r   c                  C   $   g d} g d}dd t | |D S )z-Map from pitch class (str) to semitone (int).)CDEFGAB)r               	      c                 S      i | ]\}}||qS r   r   ).0csr   r   r   
<dictcomp>       z"_pitch_classes.<locals>.<dictcomp>zip)pitch_classes	semitonesr   r   r   _pitch_classes|      r0   c                  C   r   )z+Map scale degrees (str) to semitones (int).)12345678910111213)r   r    r!   r"   r#   r$   r%   r                  c                 S   r&   r   r   )r'   dr)   r   r   r   r*      r+   z"_scale_degrees.<locals>.<dictcomp>r,   )degreesr/   r   r   r   _scale_degrees   r1   rF   c                 C   sp   d}t | D ]-\}}|dkr|dkr|d7 }q|dkr$|dkr$|d8 }q|dkr.t|}qtd|  |d S )zConvert 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.

    r   #   bz!Pitch class improperly formed: %sr   )	enumeratePITCH_CLASSESgetr   )pitch_classsemitoneidxcharr   r   r   pitch_class_to_semitone   s   

rQ   c                 C   s~   d}d}|  dr| d}| d} n|  dr%d| d }| d} t| d}|du r;td| tt || S )ae  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.
    r   rG   rI   r   Nz7Scale degree improperly formed: {}, expected one of {}.)	
startswithcountstripSCALE_DEGREESrL   r   formatlistkeys)scale_degreerN   offsetr   r   r   scale_degree_to_semitone   s    



r[   Fc                 C   sP   d}|  drd}| d} dg| }t| }||k s|r#|||| < t|S )a  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.
    rH   *r   r   )rR   rT   r[   nparray)rY   modulolengthsignedit_mapsd_idxr   r   r   scale_degree_to_bitmap   s   



rd   maj)rH   r   r   r   rH   r   r   rH   r   r   r   r   min)rH   r   r   rH   r   r   r   rH   r   r   r   r   aug)rH   r   r   r   rH   r   r   r   rH   r   r   r   dim)rH   r   r   rH   r   r   rH   r   r   r   r   r   sus4)rH   r   r   r   r   rH   r   rH   r   r   r   r   sus2)rH   r   rH   r   r   r   r   rH   r   r   r   r   r8   )rH   r   r   r   rH   r   r   rH   r   r   rH   r   maj7)rH   r   r   r   rH   r   r   rH   r   r   r   rH   min7)rH   r   r   rH   r   r   r   rH   r   r   rH   r   minmaj7)rH   r   r   rH   r   r   r   rH   r   r   r   rH   maj6)rH   r   r   r   rH   r   r   rH   r   rH   r   r   min6)rH   r   r   rH   r   r   r   rH   r   rH   r   r   dim7)rH   r   r   rH   r   r   rH   r   r   rH   r   r   hdim7)rH   r   r   rH   r   r   rH   r   r   r   rH   r   maj9min9r:   )rH   r   r   r   r   r   r   r   r   r   r   r   )rH   r   r   r   r   r   r   rH   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   )min11r<   maj13min13r>   r2   r6   r   c                 C   s"   | t vr
td|  tt |  S )zReturn the bitmap for a given quality.

    Parameters
    ----------
    quality : str
        Chord quality name.

    Returns
    -------
    bitmap : np.ndarray
        Bitmap representation of this quality (12-dim).

    zQUnsupported chord quality shorthand: '%s' Did you mean to reduce extended chords?)	QUALITIESr   r]   r^   qualityr   r   r   quality_to_bitmap  s   rz   b9#9r<   #11>   r:   r<   r>   >   r:   r<   b13)rm   rr   rs   r:   r{   r|   r<   r}   r>   r~   rt   ru   rv   c                 C   s   t | | t fS )a_  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.

    )EXTENDED_QUALITY_REDUXrL   setrx   r   r   r   reduce_extended_quality>  s   r   a=  ^((N|X)|(([A-G](b*|#*))((:(maj|min|dim|aug|1|5|sus2|sus4|maj6|min6|7|maj7|min7|dim7|hdim7|minmaj7|aug7|9|maj9|min9|11|maj11|min11|13|maj13|min13)(\((\*?((b*|#*)([1-9]|1[0-3]?))(,\*?((b*|#*)([1-9]|1[0-3]?)))*)\))?)|(:\((\*?((b*|#*)([1-9]|1[0-3]?))(,\*?((b*|#*)([1-9]|1[0-3]?)))*)\)))?((/((b*|#*)([1-9]|1[0-3]?)))?)?))$c                 C   s   t | std| dS )zTest for well-formedness of a chord label.

    Parameters
    ----------
    chord_label : str
        Chord label to validate.
    zInvalid chord label: {}N)CHORD_REmatchr   rV   )r
   r   r   r   validate_chord_label[  s   
r   c           	      C   s   t | } t|  | tkr| dt dgS d}d| v r | d\} }t }d}d| v rC| d\} }d|v }|d}dd	 |d
D }|rMd| vrMtd|rQdnd}d| v re| d\}}|rd| }n| }|rtt|\}}|	| ||||gS )aU  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.

    r   r2   /F(r\   )c                 S   s   h | ]}|  qS r   )rT   )r'   ir   r   r   	<setcomp>      zsplit.<locals>.<setcomp>,:z3Intervals specifying omissions MUST have a quality.re   )
strr   NO_CHORDr   splitrT   r   lowerr   update)	r
   reduce_extended_chordsbassscale_degreesomissionry   
chord_rootquality_nameaddl_scale_degreesr   r   r   r   h  s:    

r   r   c                 C   sR   | }|s|r|d| 7 }|r|dd | 7 }|r#|dkr#|d| 7 }t| |S )a5  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.

    z:%sz(%s)r   r2   z/%s)joinr   )r   ry   
extensionsr   r
   r   r   r   r     s   r   c                 C   s   | t krtS | tkrtS t| |d\}}}}t|}t|d }t|}	d|	d< |D ]	}
|	t|
|7 }	q*|	dk	t
j}	|	| sI|rItd|  | d|	|< ||	|fS )a  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.
    )r   r   rH   r   z5Given bass scale degree is absent from this chord: %s)r   NO_CHORD_ENCODEDX_CHORDX_CHORD_ENCODEDr   rQ   r[   rz   rd   astyper]   int64r   )r
   r   strict_bass_intervalsr   ry   r   r   root_numberbass_numbersemitone_bitmaprY   r   r   r   encode  s*   
r   c           
      C   s   t | }tjd|gtjd\}}tj|dgtjd}t }t| D ]"\}}||d}	|	du r8t||}	|	||< |	\||< ||< ||< q!|||fS )a  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.

    r    dtyper   N)lenr]   zerosr   dictrJ   rL   r   )
chord_labelsr   	num_itemsrootsbassesr/   local_cacher   labelresultr   r   r   encode_many
  s   

r   c                 C   sX   t | } | jdksJ dtt | }|d | d |d< t | }d|t|< |S )a  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.

    rH   z(Currently only 1D bitmaps are supported.r   r   )r]   asarrayndimrW   nonzero
zeros_liketuple)bitmapr   idxs
abs_bitmapr   r   r   rotate_bitmap_to_root.  s   

r   c                 C   s2   g }t | |D ]\}}|t|| qt|S )a  Circularly shift a relative bitmaps to absolute pitch classes.

    See :func:`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.

    )r-   appendr   r]   r   )bitmapsr   abs_bitmapsr   r   r   r   r   rotate_bitmaps_to_rootsQ  s   
r   c                 C   s|   t | }t |}||krtd||f | |fD ]}|D ]}t| qqt | dkr/td t |dkr<td dS dS )a'  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.
    zUChord comparison received different length lists: len(reference)=%d	len(estimates)=%dr   zReference labels are emptyzEstimated labels are emptyN)r   
ValueErrorr   warningswarn)reference_labelsestimated_labelsr   Mlabelsr
   r   r   r   validatej  s"   

r   c                 C   s   t | }|jd |krtd|jd ||dk  r tdt|dkr.td dS | dk}| dkr?td dS | | } || }t	t|}tj
|t	d| }t| | S )a6  Compute the weighted accuracy of a list of chord comparisons.

    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)

    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

    r   zaweights and comparisons should be of the same length. len(weights) = {} but len(comparisons) = {}zWeights should all be positive.zNo nonzero weights, returning 0zENo reference chords were comparable to estimated chords, returning 0.r   )r   shaper   rV   anyr]   sumr   r   floatr   )comparisonsweightsr   	valid_idxtotal_weightnormalized_weightsr   r   r   weighted_accuracy  s,   %
r   c           	      C   s   t | | t| ddd \}}t|ddd \}}||k}|dddf |dddf k}|| tj}d|tj|dk dd< |S )	a  Compare chords along root & third relationships.

    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)

    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]

    FNr             r   rH   axisr   r   r   r]   float64r   )	r   r   	ref_rootsref_semitones	est_rootsest_semitoneseq_roots	eq_thirdscomparison_scoresr   r   r   thirds  s   
" r   c                 C   s   t | | t| d\}}}t|d\}}}||k}||k}	|dddf |dddf k}
||
 |	 tj}d|tj|dk dd< |S )a  Score chords along root, third, & bass relationships.

    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)

    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]

    FNr   r   r   rH   r   r   )r   r   r   r   ref_bassr   r   est_basseq_rooteq_basseq_thirdr   r   r   r   
thirds_inv  s   
" r   c           	      C   s   t | | t| ddd \}}t|ddd \}}||k}tjt|ddddf |ddddf dd}|| tj}d|tj|dk dd< |S )	a  Compare chords along triad (root & quality to #5) relationships.

    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)

    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]

    FNr       rH   r   r   r   r   r   r]   allequalr   r   r   	r   r   r   r   r   r   r   eq_semitonesr   r   r   r   triads)  s   
"6r   c                 C   s   t | | t| d\}}}t|d\}}}||k}||k}	tjt|ddddf |ddddf dd}
||
 |	 tj}d|tj|dk dd< |S )a  Score chords along triad (root, quality to #5, & bass) relationships.

    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)

    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]

    FNr   rH   r   r   r   r   r   r   r   r   r   r   r   r   r   	eq_bassesr   r   r   r   r   
triads_invX  s   
"6r   c           	      C   s~   t | | t| ddd \}}t|ddd \}}||k}tjt||dd}|| tj}d|tj|dk dd< |S )a  Compare chords along tetrad (root & full quality) relationships.

    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)

    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]

    FNr    rH   r   r   r   r   r   r   r   r   tetrads  s   
"r   c                 C   s~   t | | t| d\}}}t|d\}}}||k}||k}	tjt||dd}
||
 |	 tj}d|tj|dk dd< |S )a  Compare chords along tetrad (root, full quality, & bass) relationships.

    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)

    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]

    FrH   r   r   r   r   r   r   r   r   tetrads_inv  s   
"r   c                 C   sX   t | | t| ddd \}}t|dd }||ktj}d|tj|dk dd< |S )a  Compare chords according to roots.

    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)

    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.
    FNr    r   r   rH   r   r   )r   r   r   r   r   r   r   r   r   root  s   
"r   c                 C   s   t | | d}t| d}t|d |d }t|d}t|d |d }|| jdd}||ktj}t|d dk|d dk}	d||	< |d dkjdd}
t|
dk|
|k }t|tj	|d dk dd| d||< |S )	a  Compare chords along MIREX rules.

    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)

    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]

    r   FrH   r   r   r   g      ?r   )
r   r   r   r   r   r]   r   logical_and
logical_orr   )r   r   min_intersectionref_data
ref_chromaest_data
est_chroma	eq_chromar   no_rootref_semitone_countskip_idxr   r   r   mirex  s"   
"

 r   c                 C   s&  t | | ttd dd }ttd dd }t| d\}}}t|d\}}}||k}	tjt|ddddf |ddddf dd}
|	|
 tj}tjt|ddddf |dd}tjt|ddddf |dd}t	|dk tj|dkdd}d	||| | dk< |S )
a  Compare chords along major-minor rules. Chords with qualities outside
    Major/minor/no-chord are ignored.

    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)

    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.

    re   Nr   rf   FrH   r   r   r   )
r   r]   r^   rw   r   r   r   r   r   r   )r   r   maj_semitonesmin_semitonesr   r   _r   r   r   
eq_qualityr   is_majis_minis_noner   r   r   majminR  s   
$6&&	r  c                 C   sf  t | | ttd dd }ttd dd }t| d\}}}t|d\}}}	||k||	k }
tjt|ddddf |ddddf dd}|
| tj}tjt|ddddf |dd}tjt|ddddf |dd}t	|dk tj|dkdd}d	||| | dk< tj
|jtd
}|dk}|||| f ||< d	||dk< |S )ao  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]).

    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)

    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.

    re   Nr   rf   FrH   r   r   r   r   )r   r]   r^   rw   r   r   r   r   r   r   onesr   bool)r   r   r   r   r   r   r   r   r   r   eq_root_bassr   r   r  r  r  valid_inversionbass_idxr   r   r   
majmin_inv  s"   
%6&&r  c                    s   t | | g d}tdd |D }t| ddd \} t|ddd \}}||k}tjt |dd}|| tj}	t fd	d|D }
d
|	tj|
dddk< |	S )a&  Compare chords along MIREX 'sevenths' rules. Chords with qualities
    outside [maj, maj7, 7, min, min7, N] are ignored.

    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)

    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.

    re   rf   rk   r8   rl   r   c                 S      g | ]}t | qS r   rw   r'   r   r   r   r   
<listcomp>  r   zsevenths.<locals>.<listcomp>FNr    rH   r   c                    "   g | ]}t jt  |d dqS rH   r   r]   r   r   r'   r/   r   r   r   r        r   r   )	r   r]   r^   r   r   r   r   r   r   )r   r   seventh_qualitiesvalid_semitonesr   r   r   r   r   r   is_validr   r  r   sevenths  s   
$
r  c                    s   t | | g d}tdd |D }t| d\} }t|d\}}}||k||k }	tjt |dd}
|	|
 tj}t fdd|D }d|tj|d	dd	k< tj	|j
td
}|d	k} ||| f ||< d||d	k< |S )a*  Compare chords along MIREX 'sevenths' rules. Chords with qualities
    outside [maj, maj7, 7, min, min7, N] are ignored.

    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)

    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.

    r  c                 S   r  r   r  r  r   r   r   r  4  r   z sevenths_inv.<locals>.<listcomp>FrH   r   c                    r  r  r  r  r  r   r   r  ?  r  r   r   r   )r   r]   r^   r   r   r   r   r   r   r  r   r  )r   r   r  r  r   
ref_bassesr   r   
est_basseseq_roots_bassesr   r   r  r	  r
  r   r  r   sevenths_inv  s&   
$
r  c           	      C   s   t | t |  t| dkr&| dddf | dddf k r&tdt| }d}| D ]%\}}|| }|||k||k @  }t|||g}||t	|
  7 }q1|| d | d   S )	aC  Compute the directional hamming distance between reference and
    estimated intervals as defined by [#harte2010towards]_ and used for MIREX
    'OverSeg', 'UnderSeg' and 'MeanSeg' measures.

    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)

    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.
    rH   Nr   r   z Chord Intervals must not overlapg        )r   rH   )r   r   )r   validate_intervalsr   r   r   r]   uniqueflattenhstackdiffmax)	reference_intervalsestimated_intervalsest_tssegstartenddurbetween_start_endseg_tsr   r   r   directional_hamming_distanceN  s   

"r.  c                 C   s   dt | | S )a  Compute the MIREX 'OverSeg' score.

    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)

    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.
    rH   r.  r%  r&  r   r   r   overseg     r1  c                 C   s   dt ||  S )a  Compute the MIREX 'UnderSeg' score.

    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)

    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.
    rH   r/  r0  r   r   r   underseg  r2  r3  c                 C   s   t t| |t| |S )a  Compute the MIREX 'MeanSeg' score.

    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)

    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.
    )rf   r3  r1  r0  r   r   r   r(    s   r(  c                 C   s   t |d\}}}g }d}d}d}t| dddf | dddf |||D ]+\}	}
}}}||ks9||k s9||krI|||}}}||	|
g q$|
|d d< q$t|S )a  
    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
        :func:`mir_eval.io.load_labeled_intervals`.
    labels : list, shape=(n,)
        Chord labels to be merged, in the format returned by
        :func:`mir_eval.io.load_labeled_intervals`.

    Returns
    -------
    merged_ivs : np.ndarray, shape=(k, 2), dtype=float
        Merged chord intervals, k <= n

    TNr   rH   r   )r   r-   r   r   r]   r^   )	intervalsr   r   r/   r   
merged_ivsprev_rtprev_stprev_bar)   ertstbar   r   r   merge_chord_intervals  s   "
r=  c           
      K   s  t |||  |  tt\}}t| |}t||}t | |||\}}}t |}t	 }	t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d< t
t||||	d	< t
t||||	d
< t
t||||	d< t
t||||	d< t|||	d< t|||	d< t|	d |	d |	d< |	S )au  Compute weighted accuracy for all comparison functions for the given
    reference and estimated annotations.

    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)

    Parameters
    ----------
    ref_intervals : np.ndarray, shape=(n, 2)
        Reference chord intervals, in the format returned by
        :func:`mir_eval.io.load_labeled_intervals`.
    ref_labels : list, shape=(n,)
        reference chord labels, in the format returned by
        :func:`mir_eval.io.load_labeled_intervals`.
    est_intervals : np.ndarray, shape=(m, 2)
        estimated chord intervals, in the format returned by
        :func:`mir_eval.io.load_labeled_intervals`.
    est_labels : list, shape=(m,)
        estimated chord labels, in the format returned by
        :func:`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.

    r   r   r   r   r   r   r   r   r  r  r  r  r3  r1  r(  )r   adjust_intervalsrf   r$  r   r=  merge_labeled_intervalsintervals_to_durationscollectionsOrderedDictr   r   r   r   r   r   r   r   r   r  r  r  r  r3  r1  )
ref_intervals
ref_labelsest_intervals
est_labelskwargsmerged_ref_intervalsmerged_est_intervalsr4  	durationsscoresr   r   r   evaluate  sR   '
	







rL  )F)r   Nr   )FF)8r   numpyr]   r   rA  remir_evalr   BITMAP_LENGTHr   r^   r   r   r   	Exceptionr   r0   rF   rK   rQ   rU   r[   rd   rw   rz   r   r   compiler   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r.  r1  r3  r(  r=  rL  r   r   r   r   <module>   s    a$"	









K
#
4$#D/0/0/0,?A@;@2#