
    3j@                   <   d Z ddlmZ ddlmZ ddlZddlZddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZ ddlmZ  ej2                  d      Z G d dej6                  e      Z G d de      Zedk(  rddlZ ej>                          yy)z
This module defines two component objects for defining nested metrical structures:
:class:`~music21.meter.core.MeterTerminal` and :class:`~music21.meter.core.MeterSequence`.
    )annotations)SequenceN)common)opFrac)SlottedObjectMixin)
OffsetQLIn)DurationDurationException)environment)MeterException)tools)prebasez
meter.corec                  N   e Zd ZdZdZdddZddZd Zd Zd Z	dd	Z
d
 ZddZ	 	 ddZedd       Zej                   dd       Zedd       Zej                   dd       Zedd       Zej                   dd       Zd Zed        Zej                   d d       Zed        Zy)!MeterTerminala9  
    A MeterTerminal is a nestable primitive of rhythmic division.

    >>> a = meter.MeterTerminal('2/4')
    >>> a.duration.quarterLength
    2.0
    >>> a = meter.MeterTerminal('3/8')
    >>> a.duration.quarterLength
    1.5
    >>> a = meter.MeterTerminal('5/2')
    >>> a.duration.quarterLength
    10.0
    )_denominator	_duration
_numerator_overriddenDuration_weightNc                    d | _         d| _        d| _        d| _        d | _        |7t        j                  |      }|j                  | _        |j                  | _        | j                          || _        y )Nr      )
r   r   r   r   r   r   slashToTuple	numeratordenominator_ratioChanged)selfslashNotationweightvaluess       ?/DATA/.local/lib/python3.12/site-packages/music21/meter/core.py__init__zMeterTerminal.__init__<   sq     )- !""#26 $ ''6F$..DO & 2 2D
     c                    | j                         }| j                  |_        | j                  |_        |j                          | j                  |_        |S )a  
        Helper method to for the deepcopy function in copy.py.

        Do not call this directly.

        Defining a custom __deepcopy__ here is a performance boost,
        particularly in not copying _duration, directly assigning _weight, and
        other benefits.
        )	__class__r   r   r   r   r   memonews      r    __deepcopy__zMeterTerminal.__deepcopy__U   sE     nn,,ll
r"   c                    t        |       S N)strr   s    r    _reprInternalzMeterTerminal._reprInternali   s    4yr"   c                    t        t        | j                              dz   t        t        | j                              z   S )N/)r+   intr   r   r,   s    r    __str__zMeterTerminal.__str__l   s0    3t~~&'#-C8H8H4I0JJJr"   c                p    |y|j                   | j                   k(  r|j                  | j                  k(  ryy)a  
        Compare the numerator and denominator of another object.
        Note that these have to be exact matches; 3/4 is not the same as 6/8

        >>> a = meter.MeterTerminal('3/4')
        >>> b = meter.MeterTerminal('6/4')
        >>> c = meter.MeterTerminal('2/4')
        >>> d = meter.MeterTerminal('3/4')
        >>> a.ratioEqual(b)
        False
        >>> a.ratioEqual(c)
        False
        >>> a.ratioEqual(d)
        True
        FTr   r   )r   others     r    
ratioEqualzMeterTerminal.ratioEqualo   s6      =OOt~~-%%)9)99r"   c                X    t               }|j                  | |d| j                         |S )a  
        returns a MeterSequence made up of taking this MeterTerminal and
        subdividing it into the given number of parts.  Each of those parts
        is a MeterTerminal

        >>> a = meter.MeterTerminal('3/4')
        >>> b = a.subdivideByCount(3)
        >>> b
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> len(b)
        3
        >>> b[0]
        <music21.meter.core.MeterTerminal 1/4>

        What happens if we do this?

        >>> a = meter.MeterTerminal('5/8')
        >>> b = a.subdivideByCount(2)
        >>> b
        <music21.meter.core.MeterSequence {2/8+3/8}>
        >>> len(b)
        2
        >>> b[0]
        <music21.meter.core.MeterTerminal 2/8>
        >>> b[1]
        <music21.meter.core.MeterTerminal 3/8>

        But what if you want to divide into 3/8+2/8 or something else?
        for that, see the :meth:`~music21.meter.MeterSequence.load` method
        of :class:`~music21.meter.MeterSequence`.
        T)
autoWeighttargetWeight)MeterSequenceloadr   )r   countRequestmss      r    subdivideByCountzMeterTerminal.subdivideByCount   s+    B _ 	lt$++N	r"   c                ^    t               }|j                  |        |j                  |       |S )a  
        Return a MeterSequence dividing this
        MeterTerminal according to the numeratorList

        >>> a = meter.MeterTerminal('3/4')
        >>> b = a.subdivideByList([1, 1, 1])
        >>> b
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> len(b)
        3
        >>> b[0]
        <music21.meter.core.MeterTerminal 1/4>

        Unequal subdivisions work:

        >>> c = a.subdivideByList([1, 2])
        >>> c
        <music21.meter.core.MeterSequence {1/4+2/4}>
        >>> len(c)
        2
        >>> (c[0], c[1])
        (<music21.meter.core.MeterTerminal 1/4>, <music21.meter.core.MeterTerminal 2/4>)

        So does subdividing by strings

        >>> c = a.subdivideByList(['2/4', '1/4'])
        >>> len(c)
        2
        >>> (c[0], c[1])
        (<music21.meter.core.MeterTerminal 2/4>, <music21.meter.core.MeterTerminal 1/4>)

        See :meth:`~music21.meter.MeterSequence.partitionByList` method
        of :class:`~music21.meter.MeterSequence` for more details.
        )r9   r:   partitionByList)r   numeratorListr<   s      r    subdivideByListzMeterTerminal.subdivideByList   s*    H _

=)	r"   c                    t               }|j                  j                  | j                  j                  k7  rt        d|       |j	                  |       |S )a  
        Return a MeterSequence based on another MeterSequence

        >>> a = meter.MeterSequence('1/4+1/4+1/4')
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> b = meter.MeterSequence('3/8+3/8')
        >>> a.subdivideByOther(b)
        <music21.meter.core.MeterSequence {{3/8+3/8}}>

        >>> terminal = meter.MeterTerminal('1/4')
        >>> divider = meter.MeterSequence('1/8+1/8')
        >>> terminal.subdivideByOther(divider)
        <music21.meter.core.MeterSequence {{1/8+1/8}}>
        zcannot subdivide by other: )r9   durationquarterLengthr   r:   )r   r4   r<   s      r    subdivideByOtherzMeterTerminal.subdivideByOther   sJ    " _>>''4==+F+FF #>ug!FGG
	r"   c                    t        j                  |      r| j                  |      S t        |t              r| j                  |      S t        j                  |      r| j                  |      S t        d|       )aY  
        Subdivision takes a MeterTerminal and, making it into a collection of MeterTerminals,
        Returns a MeterSequence.

        This is different from partitioning a MeterSequence. `subdivide` does not happen
        in place and instead returns a new object.

        If an integer is provided, assume it is a partition count.
        "cannot process partition argument )	r   
isListLikerA   
isinstancer9   rE   isNumr=   r   r   values     r    	subdividezMeterTerminal.subdivide   sn     U#''..}-((//\\% ((// #EeW!MNNr"   c                    | j                   S )z
        Return or set the weight of a MeterTerminal

        >>> a = meter.MeterTerminal('2/4')
        >>> a.weight = 0.5
        >>> a.weight
        0.5
        r   r,   s    r    r   zMeterTerminal.weight  s     ||r"   c                    || _         y r*   rO   rK   s     r    r   zMeterTerminal.weight  s	    r"   c                    | j                   S )a  
        Return or set the numerator of the MeterTerminal

        >>> a = meter.MeterTerminal('2/4')
        >>> a.numerator
        2
        >>> a.duration.quarterLength
        2.0
        >>> a.numerator = 11
        >>> a.duration.quarterLength
        11.0
        )r   r,   s    r    r   zMeterTerminal.numerator  s     r"   c                2    || _         | j                          y r*   )r   r   rK   s     r    r   zMeterTerminal.numerator+  s    r"   c                    | j                   S )a  
        Get or set the denominator of the meter terminal

        >>> a = meter.MeterTerminal('2/4')
        >>> a.denominator
        4
        >>> a.duration.quarterLength
        2.0
        >>> a.denominator = 8
        >>> a.duration.quarterLength
        1.0

        >>> a.denominator = 7
        Traceback (most recent call last):
        music21.exceptions21.MeterException: bad denominator value: 7
        )r   r,   s    r    r   zMeterTerminal.denominator0  s    $    r"   c                r    |t         j                  vrt        d|       || _        | j	                          y )Nzbad denominator value: )r   validDenominatorsSetr   r   r   rK   s     r    r   zMeterTerminal.denominatorD  s9     222 #:5'!BCC!r"   c                    t               | _        	 d| j                  z  | j                  z  | j                  _        y# t
        $ r0 t        j                  dd| j                  | j                  g       Y yw xY w)zI
        If ratio has been changed, call this to update duration
        g      @zDurationException encounteredznumerator/denominatorN)r	   r   r   r   rD   r
   environLocal
printDebugr,   s    r    r   zMeterTerminal._ratioChangedL  so     "	t~~%)9)99 NN( ! 	##0(!!	s   += 6A65A6c                J    | j                   r| j                   S | j                  S )aO  
        duration gets or sets a duration value that
        is equal in length of the terminal.

        >>> a = meter.MeterTerminal()
        >>> a.numerator = 3
        >>> a.denominator = 8
        >>> d = a.duration
        >>> d.type
        'quarter'
        >>> d.dots
        1
        >>> d.quarterLength
        1.5
        )r   r   r,   s    r    rC   zMeterTerminal.durationa  s#    " ##+++>>!r"   c                    || _         y r*   )r   rK   s     r    rC   zMeterTerminal.durationw  s
    #( r"   c                     y)za
        Return how many levels deep this part is -- the depth of a terminal is always 1
        r    r,   s    r    depthzMeterTerminal.depth{  s    
 r"   )Nr   )r   z
str | Noner   int | floatr*   )r4   z'music21.meter.MeterSequence')rL   z)Sequence[int | str] | MeterSequence | int)returnfloat | int)rL   r`   r_   r0   )rL   r0   )rL   r	   )__name__
__module____qualname____doc__	__slots__r!   r(   r-   r1   r5   r=   rA   rE   rM   propertyr   setterr   r   r   rC   r]   r\   r"   r    r   r   #   s   I2(K4&P'R0O8O2 	 	 ]]      ! !&  * " "* __) )  r"   r   c                      e Zd ZdZdZ	 	 d+	 	 	 d, fdZd-dZd.dZd Zd Z	d/dZ
d	 Zed
        Zd0dZd1dZd2dZd3d4dZd5dZd6dZ	 d7	 	 	 d8dZd-d9dZd Z	 	 d:dZed        Z	 	 	 d;	 	 	 	 	 	 	 d<dZd Zed=d       Zej8                  d>d       Zd Zd?dZed        Zed        Z ddd Z!d3d@d!Z"dAd"Z#dBd#Z$dBd$Z%dBd%Z&d7dCd&Z'd7d'Z(d7d(Z)d) Z*dDdEd*Z+ xZ,S )Fr9   zO
    A meter sequence is a list of MeterTerminals, or other MeterSequences
    )_levelListCache
_partitionparenthesissummedNumeratorc                    t         |           d| _        d| _        g | _        i | _        d| _        d| _        || j                  ||       y y )Nr   r   F)	superr!   r   r   rk   rj   rm   rl   r:   )r   rL   partitionRequestr$   s      r    r!   zMeterSequence.__init__  s\    
 	 !"=?LN &+ "'IIe-. r"   c                :   | j                         }| j                  |_        | j                  |_        t        j                  | j
                  |      |_        |j                          | j                  |_        | j                  |_        | j                  |_	        |S )a  
        Helper method to copy.py's deepcopy function. Call it from there.

        Defining a custom __deepcopy__ here is a performance boost,
        particularly in not copying _duration and other benefits.

        Notably, self._levelListCache is not copied,
        which may not be needed in the copy and may be large.

        >>> from copy import deepcopy
        >>> ms1 = meter.MeterSequence('4/4+3/8')
        >>> ms2 = deepcopy(ms1)
        >>> ms2
        <music21.meter.core.MeterSequence {4/4+3/8}>
        )
r$   r   r   copydeepcopyrk   r   r   rm   rl   r%   s      r    r(   zMeterSequence.__deepcopy__  s{    " nn,,t= #'":":"22**
r"   c                Z    t        |      t        |       k\  rt        | j                  |   S )z
        Get an MeterTerminal (or MeterSequence) from _partition

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a[3].numerator
        1
        )abslen
IndexErrorrk   )r   keys     r    __getitem__zMeterSequence.__getitem__  s)     s8s4y s##r"   c                ,    t        | j                        S )z
        Support iteration of top level partitions

        >>> a = meter.MeterSequence('4/4', 2)
        >>> for x in a:
        ...     print(repr(x))
        <music21.meter.core.MeterTerminal 1/2>
        <music21.meter.core.MeterTerminal 1/2>
        )iterrk   r,   s    r    __iter__zMeterSequence.__iter__  s     DOO$$r"   c                ,    t        | j                        S )z
        Return the length of the partition list

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> len(a)
        4
        )rv   rk   r,   s    r    __len__zMeterSequence.__len__  s     4??##r"   c                    t        |t              st        d|       |j                  | |         r|| j                  |<   i | _        yt        d| d| |          )a  
        Insert items at index positions.

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> a[0]
        <music21.meter.core.MeterTerminal 1/4>
        >>> a[0] = a[0].subdivide(2)
        >>> a
        <music21.meter.core.MeterSequence {{1/8+1/8}+1/4+1/4+1/4}>
        >>> a[0][0] = a[0][0].subdivide(2)
        >>> a
        <music21.meter.core.MeterSequence {{{1/16+1/16}+1/8}+1/4+1/4+1/4}>
        >>> a[3]
        <music21.meter.core.MeterTerminal 1/4>
        >>> a[3] = a[0][0]
        Traceback (most recent call last):
        ...
        music21.exceptions21.MeterException: cannot insert {1/16+1/16} into space of 1/4
        zGvalues in MeterSequences must be MeterTerminals or MeterSequences, not zcannot insert z into space of N)rI   r   r   r5   rk   rj   )r   rx   rL   s      r    __setitem__zMeterSequence.__setitem__  su    . %/  "88=w"@ A ADI&#(DOOC 
  " !>%S	{!STTr"   c                &    d| j                   z   dz   S )N{})partitionDisplayr,   s    r    r1   zMeterSequence.__str__  s    T***S00r"   c                ~    g }| j                   D ]  }|j                  t        |              dj                  |      S )a  
        Property -- Display the partition as a str without the surrounding curly brackets.

        >>> a = meter.MeterSequence('4/4')
        >>> a.partitionDisplay
        '4/4'
        >>> a = meter.MeterSequence('2/4+6/8')
        >>> a.partitionDisplay
        '2/4+6/8'

        partitionDisplay is most useful for non-divided meter sequences. This is less helpful:

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a.partitionDisplay
        '1/4+1/4+1/4+1/4'
        +)rk   appendr+   join)r   msgmts      r    r   zMeterSequence.partitionDisplay  s5    $ //BJJs2w "xx}r"   c                     g | _         i | _        y)zU
        This will not sync with .numerator and .denominator if called alone
        N)rk   rj   r,   s    r    _clearPartitionzMeterSequence._clearPartition5  s     !r"   c                    t        |t              r|}nt        |      }| j                  j                  |       i | _        y)a  
        Add an object to the partition list. This does not update numerator and denominator.

        ???: (targetWeight is the expected total Weight for this MeterSequence. This
        would be self.weight, but often partitions are cleared before _addTerminal is called.)
        N)rI   r   rk   r   rj   )r   rL   r   s      r    _addTerminalzMeterSequence._addTerminal=  s9     e]+Bu%B 	r"!r"   c                (   t        | j                        }t        | j                        }g }|j                  t	        t        j                  ||                   |j                  t	        t        j                  ||                   t        |      S )aE  
        Return either a cached or a new set of division/partition options.

        Calls `tools.divisionOptionsAlgo` and `tools.divisionOptionsPreset`
        (which will be empty except if the numerator is 5).

        Works on anything that has a .numerator and .denominator.

        >>> meter.MeterSequence('3/4').getPartitionOptions()
        (('1/4', '1/4', '1/4'),
         ('1/8', '1/8', '1/8', '1/8', '1/8', '1/8'),
         ('1/16', '1/16', '1/16', '1/16', '1/16', '1/16', '1/16',
          '1/16', '1/16', '1/16', '1/16', '1/16'),
         ('3/4',), ('6/8',), ('12/16',), ('24/32',), ('48/64',), ('96/128',))

        The additional 2 + 2 + 1 and 2 + 1 + 2 options for numerator 5 are at the end.

        >>> meter.MeterSequence('5/32').getPartitionOptions()
        (('2/32', '3/32'),
         ('3/32', '2/32'),
         ('1/32', '1/32', '1/32', '1/32', '1/32'),
         ('1/64', '1/64', '1/64', '1/64', '1/64',
          '1/64', '1/64', '1/64', '1/64', '1/64'),
         ('5/32',), ('10/64',), ('20/128',),
         ('2/32', '2/32', '1/32'), ('2/32', '1/32', '2/32'))
        )	r0   r   r   extendlistr   divisionOptionsAlgodivisionOptionsPresettuple)r   ndoptss       r    getPartitionOptionsz!MeterSequence.getPartitionOptionsU  sm    8   !D221a89:D44Q:;<T{r"   c           	     H   | j                         }d}|D ]  }t        |      |k(  s|} n |3|r|r|d   }n)t        d| d| j                   d| j                   d      | j
                  }| j                          |D ]  }| j                  |        || _        i | _        y)a%  
        Divide the current MeterSequence into the requested number of parts.

        If it is not possible to divide it into the requested number, and
        loadDefault is `True`, then give the default partition:

        This will destroy any established structure in the stored partition.

        >>> a = meter.MeterSequence('4/4')
        >>> a
        <music21.meter.core.MeterSequence {4/4}>
        >>> a.partitionByCount(2)
        >>> a
        <music21.meter.core.MeterSequence {1/2+1/2}>
        >>> str(a)
        '{1/2+1/2}'
        >>> a.partitionByCount(4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> str(a)
        '{1/4+1/4+1/4+1/4}'

        The partitions are not guaranteed to be the same length if the
        meter is irregular:

        >>> b = meter.MeterSequence('5/8')
        >>> b.partitionByCount(2)
        >>> b
         <music21.meter.core.MeterSequence {2/8+3/8}>

        This relies on a pre-defined exemption for partitioning 5 by 3:

        >>> b.partitionByCount(3)
        >>> str(b)
        '{2/8+2/8+1/8}'

        Here we use loadDefault=True to get the default partition in case
        there is no known way to do this:

        >>> a = meter.MeterSequence('5/8')
        >>> a.partitionByCount(11)
        >>> str(a)
        '{2/8+3/8}'

        If loadDefault is False then an error is raised:

        >>> a.partitionByCount(11, loadDefault=False)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: Cannot set partition by 11 (5/8)

        Nr   Cannot set partition by  (r/   ))	r   rv   r   r   r   r   r   r   rj   )r   r;   loadDefaultr   optMatchoptr8   mStrs           r    partitionByCountzMeterSequence.partitionByCount{  s    h '') C3x<'  t7$.|nBt~~>NaPTP`P`Oaabc  {{Dd# "  "r"   c           	     n   d}t        |d   t              rt               }|D ]+  }|j                  t	        j
                  t        |             - |j                          | j                  j                  |j                  j                  k(  r|}n.t        d|       t        t	        j
                  t        t           |            t        dd      D cg c]  }| j                  |z   c}v rt        dd      D ]u  }t        t	        j
                  t        t           |            | j                  |z  k(  s>g }|D ]%  }|j                  | d| j                   |z          ' t#        |      } nL nJ| j%                         }	|	D ]5  }
|
D cg c]  }t        |j'                  d      d         ! }}||k(  s3|
} n |)t        d| d| j                   d| j                    d      | j(                  }| j+                          |D ]  }| j                  |        || _        i | _        yc c}w c c}w )	a  
        Given a numerator list, partition MeterSequence into a new list
        of MeterTerminals

        >>> a = meter.MeterSequence('4/4')
        >>> a.partitionByList([1, 1, 1, 1])
        >>> str(a)
        '{1/4+1/4+1/4+1/4}'

        This divides it into two equal parts:

        >>> a.partitionByList([1, 1])
        >>> str(a)
        '{1/2+1/2}'

        And now into one big part:

        >>> a.partitionByList([1])
        >>> str(a)
        '{1/1}'

        Here we divide 4/4 very unconventionally:

        >>> a.partitionByList(['3/4', '1/8', '1/8'])
        >>> a
        <music21.meter.core.MeterSequence {3/4+1/8+1/8}>

        But the basics of the MeterSequence must be observed:

        >>> a.partitionByList(['3/4', '1/8', '5/8'])
        Traceback (most recent call last):
        music21.exceptions21.MeterException: Cannot set partition by ['3/4', '1/8', '5/8']
        Nr   r   r   	   r/   r   r   )rI   r+   r9   r   tcast_updateRatiorC   rD   r   sumr   r0   ranger   r   r   r   r   splitr   r   rj   )r   r@   r   testmtStrxioptMatchInnerr   r   r   nFoundr8   r   s                 r    r?   zMeterSequence.partitionByList  s   D <@ mA&, ?D&!!!&&e"45 '}}**dmm.I.II$'?%OPPS	=12SXYZ\]S^6_S^at~~7IS^6__1a[qvvd3i78DNNQ<NN/1M*%,,s!D4D4Dq4H3I-JK +$]3H ! ++-D8;<1#aggcl1o.<]*"H   *=/DNN;K1TM]M]L^^_` 
 {{Dd# "  "A 7` =s   H-$H2c                (   | j                   |j                   k(  ro| j                  |j                  k(  rV| j                  }| j                          |D ]&  }| j	                  t        j                  |             ( || _        i | _        yt        d      )aO  
        Set partition to that found in another
        MeterSequence.

        >>> a = meter.MeterSequence('4/4', 4)
        >>> str(a)
        '{1/4+1/4+1/4+1/4}'

        >>> b = meter.MeterSequence('4/4', 2)
        >>> a.partitionByOtherMeterSequence(b)
        >>> len(a)
        2
        >>> str(a)
        '{1/2+1/2}'
        z/Cannot set partition for unequal MeterSequencesN)	r   r   r   r   r   rr   rs   r   rj   )r   r4   r8   r   s       r    partitionByOtherMeterSequencez+MeterSequence.partitionByOtherMeterSequence  s}      NNeoo-$$(9(99;;L  "!!$--"34 &DK
  " !!RSSr"   c                    t        j                  |      r| j                  |       yt        |t              r| j                  |       yt        |t              r| j                  ||       yt        d|       )au  
        Partitioning creates and sets a number of MeterTerminals
        that make up this MeterSequence.

        A simple way to partition based on argument time. Single integers
        are treated as beat counts; lists are treated as numerator lists;
        MeterSequence objects are partitioned by calling partitionByOtherMeterSequence().

        >>> a = meter.MeterSequence('5/4+3/8')
        >>> len(a)
        2
        >>> str(a)
        '{5/4+3/8}'

        >>> b = meter.MeterSequence('13/8')
        >>> len(b)
        1
        >>> str(b)
        '{13/8}'
        >>> b.partition(13)
        >>> len(b)
        13
        >>> str(b)
        '{1/8+1/8+1/8+...+1/8}'

        >>> a.partition(b)
        >>> len(a)
        13
        >>> str(a)
        '{1/8+1/8+1/8+...+1/8}'

        Demo of loadDefault: if impossible, then do it another way:

        >>> c = meter.MeterSequence('3/128')
        >>> c.partition(2)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: Cannot set partition by 2 (3/128)

        >>> c = meter.MeterSequence('3/128')
        >>> c.partition(2, loadDefault=True)
        >>> len(c)
        3
        >>> str(c)
        '{1/128+1/128+1/128}'

        * Changed in v9.3: if given a list it must either be all numbers, all strings,
          or all MeterTerminals, not a mix (which was undocumented and buggy)
        )r   rG   N)	r   rH   r?   rI   r9   r   r0   r   r   )r   rL   r   s      r    	partitionzMeterSequence.partition;  si    j U#  '}-..u5s#!!%[!A #EeW!MNNr"   c                    d}t        t        |             D ]H  }|+| |   j                  }|dv rd}n|dk(  rd}n|dv r|dz  }n|}n|}| |   j                  |      | |<   J i | _        y)aK
  
        Subdivide all partitions by equally-spaced divisions,
        given a divisions value. Manipulates this MeterSequence in place.

        Divisions value may optionally be a MeterSequence,
        from which a top-level partitioning structure is derived.

        Example:  First we will do a normal partition (not subdivided partition)

        >>> ms = meter.MeterSequence('2/4')
        >>> ms
        <music21.meter.core.MeterSequence {2/4}>
        >>> len(ms)
        1
        >>> ms[0]
        <music21.meter.core.MeterTerminal 2/4>
        >>> len(ms[0])
        Traceback (most recent call last):
        TypeError: object of type 'MeterTerminal' has no len()

        Divide the Sequence into two parts, so now there are two
        MeterTerminals of 1/4 each:

        >>> ms.partition(2)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+1/4}>
        >>> len(ms)
        2
        >>> ms[0]
        <music21.meter.core.MeterTerminal 1/4>
        >>> ms[1]
        <music21.meter.core.MeterTerminal 1/4>

        But what happens if we want to divide each of those into 1/8+1/8 are replace
        them by MeterSequences?  subdividePartitionsEqual is what is needed.

        >>> ms.subdividePartitionsEqual(2)
        >>> ms
        <music21.meter.core.MeterSequence {{1/8+1/8}+{1/8+1/8}}>

        Length is still 2, but each of the components are now MeterSequences of their
        own:

        >>> len(ms)
        2
        >>> ms[0]
        <music21.meter.core.MeterSequence {1/8+1/8}>
        >>> ms[1]
        <music21.meter.core.MeterSequence {1/8+1/8}>

        There is not a way (the authors know of) to get to the next level.
        You would just need to do them individually.

        >>> ms[0].subdividePartitionsEqual(2)
        >>> ms
        <music21.meter.core.MeterSequence {{{1/16+1/16}+{1/16+1/16}}+{1/8+1/8}}>
        >>> ms[1].subdividePartitionsEqual(2)
        >>> ms
        <music21.meter.core.MeterSequence {{{1/16+1/16}+{1/16+1/16}}+{{1/16+1/16}+{1/16+1/16}}}>

        If None is given as a parameter, then it will try to find something logical.

        >>> ms = meter.MeterSequence('2/4+3/4')
        >>> ms.subdividePartitionsEqual(None)
        >>> ms
        <music21.meter.core.MeterSequence {{1/4+1/4}+{1/4+1/4+1/4}}>

        If any partition cannot be divided by the given count, a MeterException is raised:

        >>> ms = meter.MeterSequence('5/8+3/8')
        >>> len(ms)
        2
        >>> ms.subdividePartitionsEqual(5)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: Cannot set partition by 5 (3/8)

        r   N)r                   @   r      )   r                     )r   rv   r   rM   rj   )r   	divisionsdivisionsLocalr   partitionNumerators        r    subdividePartitionsEqualz&MeterSequence.subdividePartitionsEqualy  s    \  s4y!A *.q'*;*;"%)AA%&N'1,%&N'+II%71%<N &8N!* 1g''7DG! "&  "r"   c                    |D ]  }|j                  |        g }|D ]  }|D ]  }|j                  |         i | _        |S )a  
        Recursive nested call routine. Returns a list of the MeterSequences at the newly created
        level.

        >>> ms = meter.MeterSequence('2/4')
        >>> ms.partition(2)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+1/4}>
        >>> ms[0]
        <music21.meter.core.MeterTerminal 1/4>

        >>> post = ms._subdivideNested([ms], 2)
        >>> ms
        <music21.meter.core.MeterSequence {{1/8+1/8}+{1/8+1/8}}>
        >>> ms[0]
        <music21.meter.core.MeterSequence {1/8+1/8}>
        >>> post
        [<music21.meter.core.MeterSequence {1/8+1/8}>, <music21.meter.core.MeterSequence {1/8+1/8}>]
        >>> ms[0] is post[0]
        True

        >>> post2 = ms._subdivideNested(post, 2)  # pass post here
        >>> ms
        <music21.meter.core.MeterSequence {{{1/16+1/16}+{1/16+1/16}}+{{1/16+1/16}+{1/16+1/16}}}>
        >>> post2
        [<music21.meter.core.MeterSequence {1/16+1/16}>,
         <music21.meter.core.MeterSequence {1/16+1/16}>,
         <music21.meter.core.MeterSequence {1/16+1/16}>,
         <music21.meter.core.MeterSequence {1/16+1/16}>]

        Notice that since we gave a list of lists, post2 is now one level down

        >>> post2[0] is ms[0]
        False
        >>> post2[0] is ms[0][0]
        True

        )r   r   rj   )r   processObjListr   objpostsubs         r    _subdivideNestedzMeterSequence._subdivideNested  sS    P "C((3 " !CC   "  "r"   c                   | j                  d       d}t        |t              r&| j                  |j	                  d             |dz  }n4|| j
                  }|dv rd}n	|dv rd}n|}| j                  |       |dz  }| d   g}||k  r| j                  |d      }|dz  }|s 	 g }|D ],  }|j                  |vs|j                  |j                         . t        |      dkD  rhg }	t        t        |            D ]L  }
||
   j                  t        |      k(  r|	| j                  ||
   gd      z  }	9|	j                  ||
          N |	}nn||k  ri | _        y)	a  
        Create nested structure down to a specified depth;
        the first division is set to one; the second division
        may be by 2 or 3; remaining divisions are always by 2.

        This a destructive procedure that will remove
        any existing partition structures.

        `normalizeDenominators`, if True, will reduce all denominators to the same minimum level.

        >>> ms = meter.MeterSequence('4/4')
        >>> ms.subdivideNestedHierarchy(1)
        >>> ms
        <music21.meter.core.MeterSequence {{1/2+1/2}}>
        >>> ms.subdivideNestedHierarchy(2)
        >>> ms
        <music21.meter.core.MeterSequence {{{1/4+1/4}+{1/4+1/4}}}>
        >>> ms.subdivideNestedHierarchy(3)
        >>> ms
        <music21.meter.core.MeterSequence {{{{1/8+1/8}+{1/8+1/8}}+{{1/8+1/8}+{1/8+1/8}}}}>

        I think you get the picture!

        The effects above are not cumulative.  Users can skip directly to
        whatever level of hierarchy they want.

        >>> ms2 = meter.MeterSequence('4/4')
        >>> ms2.subdivideNestedHierarchy(3)
        >>> ms2
        <music21.meter.core.MeterSequence {{{{1/8+1/8}+{1/8+1/8}}+{{1/8+1/8}+{1/8+1/8}}}}>
        r   r   N)r   r   r   r   r   r   r   )r   r   )r   )r   rI   r9   r:   getLevelr   r   r   r   r   rv   r   minrj   )r   r]   firstPartitionFormnormalizeDenominators
depthCountdivFirstr   r   refpostNewr   s              r    subdivideNestedHierarchyz&MeterSequence.subdivideNestedHierarchy  s   D 	q

 (-8 II(11!45!OJ!)%)^^"!%99#s* . ))(3!OJ Qy5 (((>D!OJ(Ca/1   q6A: G"3t9-  7..#a&8#t'<'<d1gYGK (= (M MG $NN473 . #D)  5 >  "r"   c                ^    t        |       }d}|t        |      k  r||   S t        |      dz   S )a  
        Return the number of top-level partitions in this MeterSequence as a string.

        >>> ms = meter.MeterSequence('2/4+2/4')
        >>> ms
        <music21.meter.core.MeterSequence {2/4+2/4}>
        >>> ms.partitionStr
        'Duple'

        >>> ms = meter.MeterSequence('6/4', 6)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4+1/4+1/4}>
        >>> ms.partitionStr
        'Sextuple'

        >>> ms = meter.MeterSequence('6/4', 2)
        >>> ms.partitionStr
        'Duple'

        >>> ms = meter.MeterSequence('6/4', 3)
        >>> ms.partitionStr
        'Triple'

        Anything larger than 8 is simply the number followed by '-uple'

        >>> ms = meter.MeterSequence('13/4', 13)
        >>> ms.partitionStr
        '13-uple'

        Single partition:

        >>> ms = meter.MeterSequence('3/4', 1)
        >>> ms.partitionStr
        'Single'
        )	EmptySingleDupleTriple	Quadruple	QuintupleSextupleSeptupleOctuplez-uple)rv   r+   )r   count	countNames      r    partitionStrzMeterSequence.partitionStrz  s=    J D	8	
 3y>!U##u:''r"   c                   |r|| j                   }nd}| j                          t        |t              rbt	        j
                  |      \  }| _        |D ]&  \  }}| d| }| j                  t        |             ( | j                          ||| _         nt        |t              r+|||_         | j                  |       | j                          nUt        j                  |      r2|D ]  }	| j                  |	        | j                          ||| _         nt        d|      || j                  |       i | _        y)aW  
        This method is called when a MeterSequence is created, or if a MeterSequence is re-set.

        User can enter a list of values or an abbreviated slash notation.

        autoWeight, if True, will attempt to set weights.
        targetWeight, if given, will be used instead of self.weight

        loading is a destructive operation.

        >>> a = meter.MeterSequence()
        >>> a.load('4/4', 4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> str(a)
        '{1/4+1/4+1/4+1/4}'

        >>> a.load('4/4', 2)  # request 2 beats
        >>> a
        <music21.meter.core.MeterSequence {1/2+1/2}>
        >>> str(a)
        '{1/2+1/2}'

        >>> a.load('5/8', 2)  # request 2 beats
        >>> str(a)
        '{2/8+3/8}'

        >>> a.load('5/8+4/4')
        >>> str(a)
        '{5/8+4/4}'
        Nr/   z%cannot create a MeterSequence with a )r   r   rI   r+   r   slashMixedToFractionrm   r   r   r   r   
isIterabler   r   rj   )
r   rL   rp   r7   r8   	ratioListr   r   r   r   s
             r    r:   zMeterSequence.load  s=   T ##{{L 	eS!.3.H.H.O+It+!1#$#Qqc
!!-">? " '*}- '+e$ u%!!#&  '* #H	!RSS'NN+,  "r"   c                    t        d | j                  D              }t        j                  |      \  | _        | _        | j                          y)z
        Look at _partition to determine the total
        numerator and denominator values for this sequence

        This should only be called internally, as MeterSequences
        are supposed to be immutable (mostly)
        c              3  L   K   | ]  }|j                   |j                  f  y wr*   r3   ).0r   s     r    	<genexpr>z-MeterSequence._updateRatio.<locals>.<genexpr>  s     P"bnn5s   "$N)r   rk   r   fractionSumr   r   r   )r   fTuples     r    r   zMeterSequence._updateRatio  s@     PPP .3->->v-F**r"   c                J    d}| j                   D ]  }||j                  z  } |S )aI  
        Get the weight for the MeterSequence, or set the weight and thereby change the weights
        for each object in this MeterSequence.

        By default, all the partitions of a MeterSequence's weights sum to 1.0

        >>> a = meter.MeterSequence('3/4')
        >>> a.weight
        1.0
        >>> a.partition(3)
        >>> a
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> a.weight
        1.0
        >>> a[0].weight
        0.3333...

        But this MeterSequence might be embedded in another one, so perhaps
        its weight should be 0.5?

        >>> a.weight = 0.5
        >>> a[0].weight
        0.16666...

        When creating a new MeterSequence from MeterTerminals, the sequence has
        the weight of the sum of those creating it.

        >>> downbeat = meter.MeterTerminal('1/4', 0.5)
        >>> upbeat = meter.MeterTerminal('1/4', 0.25)
        >>> accentSequence = meter.MeterSequence([downbeat, upbeat])
        >>> accentSequence.weight
        0.75

        Changing the weight of the child sequence will affect the parent, since this is
        not cached, but recomputed on each call.

        >>> downbeat.weight = 0.375
        >>> accentSequence.weight
        0.625

        Changing the weight on the parent sequence will reset weights on the children

        >>> accentSequence.weight = 1.0
        >>> (downbeat.weight, upbeat.weight)
        (0.5, 0.5)

        Assume this MeterSequence is a whole, not a part of some larger MeterSequence.
        Thus, we cannot use numerator/denominator relationship
        as a scalar.
                )rk   r   )r   	summationr   s      r    r   zMeterSequence.weight  s,    h 	??C#I #r"   c                   t        j                  |      st        d      	 | j                  | j                  z  }| j                  D ](  }|j                  |j                  z  }|||z  z  |_        * y # t
        $ rW}t        d| j                   dt        | j                         d| j                   dt        | j                               |d }~ww xY w)Nzweight values must be numbersz0Something wrong with the type of this numerator  z or this denominator )	r   rJ   r   r   r   	TypeErrortyperk   r   )r   rL   
totalRatioter   	partRatios         r    r   zMeterSequence.weightS  s     ||E" !@AA	4+<+<<J //B7IZ!78BI "  	 ""&//!2!D4I3J K''+'8'8&94@Q@Q;R:SU 		s   A3 3	C<ACCc                    g }| j                   D ]7  }t        |t              s|j                  |       %||j	                         z  }9 |S )a#  
        Return a flattened version of this
        MeterSequence as a list of MeterTerminals.

        This return a list and not a new MeterSequence b/c MeterSequence objects
        are generally immutable and thus it does not make sense
        to concatenate them.

        >>> a = meter.MeterSequence('3/4')
        >>> a.partition(3)
        >>> b = a._getFlatList()
        >>> b
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>]
        >>> len(b)
        3

        >>> a[1] = a[1].subdivide(4)
        >>> len(a)
        3
        >>> a
        <music21.meter.core.MeterSequence {1/4+{1/16+1/16+1/16+1/16}+1/4}>

        >>> b = a._getFlatList()
        >>> len(b)
        6
        >>> b
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/16>,
         <music21.meter.core.MeterTerminal 1/16>,
         <music21.meter.core.MeterTerminal 1/16>,
         <music21.meter.core.MeterTerminal 1/16>,
         <music21.meter.core.MeterTerminal 1/4>]

        >>> a[1][2] = a[1][2].subdivide(4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+{1/16+1/16+{1/64+1/64+1/64+1/64}+1/16}+1/4}>
        >>> b = a._getFlatList()
        >>> len(b)
        9
        )rk   rI   r9   r   _getFlatList)r   mtListr   s      r    r   zMeterSequence._getFlatListj  sH    X ??Cc=1c"#**,,	 #
 r"   c                X    t               }|j                  | j                                |S )aE  
        Return a new MeterSequence composed of the flattened representation.

        Here a sequence is already flattened:

        >>> ms = meter.MeterSequence('3/4', 3)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> b = ms.flatten()
        >>> b
        <music21.meter.core.MeterSequence {1/4+1/4+1/4}>
        >>> len(b)
        3
        >>> b is ms
        False

        Now take the original MeterSequence and subdivide the second beat into 4 parts:

        >>> ms[1] = ms[1].subdivide(4)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+{1/16+1/16+1/16+1/16}+1/4}>
        >>> b = ms.flatten()
        >>> len(b)
        6
        >>> b
        <music21.meter.core.MeterSequence {1/4+1/16+1/16+1/16+1/16+1/4}>

        >>> ms[1][2] = ms[1][2].subdivide(4)
        >>> ms
        <music21.meter.core.MeterSequence {1/4+{1/16+1/16+{1/64+1/64+1/64+1/64}+1/16}+1/4}>
        >>> b = ms.flatten()
        >>> len(b)
        9
        >>> b
        <music21.meter.core.MeterSequence {1/4+1/16+1/16+1/64+1/64+1/64+1/64+1/16+1/4}>
        )r9   r:   r   )r   r   s     r    flattenzMeterSequence.flatten  s&    J 		$##%&r"   c                j    g }| j                         D ]  }|j                  |j                          |S )z5
        Return a list of flat weight values
        )r   r   r   )r   r   r   s      r    
flatWeightzMeterSequence.flatWeight  s1    
 ##%BKK		" &r"   c                P    d}d}	 | j                  |      }||k7  r|dz  }|}n	 |S ")z
        Return how many unique levels deep this part is
        This should be optimized to store values unless the structure has changed.
        r   Nr   )getLevelList)r   r]   	lastMatchr   s       r    r]   zMeterSequence.depth  sD     	$$U+Dy 
 	 r"   r   )r]   c                  g }g }| j                  |      D ]r  }|j                  |vr|j                  |j                         |j                  |vr|j                  |j                         t	        |      dkD  st	        |      dkD  sr y y)a  
        Return True if the top-level partitions (if depth=0)
        or a lower-level section has equal durations

        >>> ms = meter.MeterSequence('3/8+2/8+3/4')
        >>> ms.isUniformPartition()
        False
        >>> ms = meter.MeterSequence('4/4')
        >>> ms.isUniformPartition()
        True
        >>> ms.partition(4)
        >>> ms.isUniformPartition()
        True
        >>> ms[0] = ms[0].subdivideByCount(2)
        >>> ms[1] = ms[1].subdivideByCount(4)
        >>> ms.isUniformPartition()
        True
        >>> ms.isUniformPartition(depth=1)
        False

        >>> ms = meter.MeterSequence('2/4+2/4')
        >>> ms.isUniformPartition()
        True

        >>> ms = meter.MeterSequence('5/8', 5)
        >>> ms.isUniformPartition()
        True
        >>> ms.partition(2)
        >>> ms.isUniformPartition()
        False

        * Changed in v7: depth is keyword only.
        r   FT)r   r   r   r   rv   )r   r]   r   r   r<   s        r    isUniformPartitionz MeterSequence.isUniformPartition  sy    F ##E*B||1$&~~Q&(1vzSVaZ + r"   c                X   ||f}	 t        t        | j                  |               S # t        $ r Y nw xY wg }t	        t        | j                              D ]  }| j                  |   }t        |t              s| |   }|j                  |       9|dkD  r||j                  |dz
  |      z  }W|rGt        |j                   d|j                         }|j                  |_        |j                  |       |j                  |        t        t        |            | j                  |<   |S )a  
        Recursive utility function that gets everything at a certain level.

        If flat is True, it guarantees to return a list of MeterTerminals and not
        MeterSequences.  Otherwise, there may be Sequences in there.

        Example: a Sequence representing something in 4/4 divided as
        1 quarter, 2 eighth, 1 quarter, ((2-sixteenths) + 1 eighth).

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>

        Get the top level of this structure, flattening everything underneath:

        >>> b.getLevelList(0)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>]

        One level down:

        >>> b.getLevelList(1)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/8>,
         <music21.meter.core.MeterTerminal 1/8>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/8>,
         <music21.meter.core.MeterTerminal 1/8>]

        Without flattening, first two levels:

        >>> b.getLevelList(0, flat=False)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterSequence {1/8+1/8}>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterSequence {{1/16+1/16}+1/8}>]

        (Note that levelList 0, flat=False is essentially the same as iterating
        over a MeterSequence)

        >>> list(b)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterSequence {1/8+1/8}>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterSequence {{1/16+1/16}+1/8}>]

        >>> b.getLevelList(1, flat=False)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/8>,
         <music21.meter.core.MeterTerminal 1/8>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterSequence {1/16+1/16}>,
         <music21.meter.core.MeterTerminal 1/8>]

        Generally, these level lists will be converted back to MeterSequences:

        >>> meter.MeterSequence(b.getLevelList(0))
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> meter.MeterSequence(b.getLevelList(1))
        <music21.meter.core.MeterSequence {1/4+1/8+1/8+1/4+1/8+1/8}>
        >>> meter.MeterSequence(b.getLevelList(2))
        <music21.meter.core.MeterSequence {1/4+1/8+1/8+1/4+1/16+1/16+1/8}>
        >>> meter.MeterSequence(b.getLevelList(3))
        <music21.meter.core.MeterSequence {1/4+1/8+1/8+1/4+1/16+1/16+1/8}>

        OMIT_FROM_DOCS

        Test that cache is used and does not get manipulated

        >>> b = meter.MeterSequence('3/4', 3)
        >>> (0, True) in b._levelListCache
        False
        >>> o = b.getLevelList(0)

        Mess with the list:

        >>> o.append(meter.core.MeterTerminal('1/8'))
        >>> o
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/8>]

        Cache is populated:

        >>> (0, True) in b._levelListCache
        True

        But a new list is created.

        >>> b.getLevelList(0)
        [<music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>,
         <music21.meter.core.MeterTerminal 1/4>]

        >>> b.getLevelList(0)[0] is o[0]
        True
        r   r   r/   )r   r   rj   KeyErrorr   rv   rk   rI   r9   r   r   r   r   r   r   )r   
levelCountflatcacheKeyr   r   partition_ir   s           r    r   zMeterSequence.getLevelList  s(   P %	d228<=>> 		 ')s4??+,A7;q7IKk=9!Wb!> k66"Q. .F **445Q{7N7N6OP %0$6$6	b)k2+ -0 *.eFm)<X&s    ' 	33c                8    t        | j                  ||            S )a  
        Return a complete MeterSequence with the same numerator/denominator
        relationship but that represents any partitions found at the requested
        level. A sort of flatness with variable depth.

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
        >>> b.getLevel(0)
        <music21.meter.core.MeterSequence {1/4+1/4+1/4+1/4}>
        >>> b.getLevel(1)
        <music21.meter.core.MeterSequence {1/4+1/8+1/8+1/4+1/8+1/8}>
        >>> b.getLevel(2)
        <music21.meter.core.MeterSequence {1/4+1/8+1/8+1/4+1/16+1/16+1/8}>
        )r9   r   )r   levelr  s      r    r   zMeterSequence.getLevel  s    & T..ud;<<r"   c                    | j                  |d      }g }d}t        t        |            D ]>  }|}t        |||   j                  j
                  z         }|j                  ||f       |}@ |S )a  
        For a given level, return the time span of each terminal or sequence

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
        >>> b.getLevelSpan(0)
        [(0.0, 1.0), (1.0, 2.0), (2.0, 3.0), (3.0, 4.0)]
        >>> b.getLevelSpan(1)
        [(0.0, 1.0), (1.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 3.5), (3.5, 4.0)]
        >>> b.getLevelSpan(2)
        [(0.0, 1.0), (1.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 3.25), (3.25, 3.5), (3.5, 4.0)]
        T)r  r   )r   r   rv   r   rC   rD   r   )r   r  r<   mappingposr   startends           r    getLevelSpanzMeterSequence.getLevelSpan  ss    " u40s2wAEr!u~~;;;<CNNE3<(C	  
 r"   c                l    g }| j                  |      D ]  }|j                  |j                          |S )a~  
        The weightList is an array of weights found in the components.
        The MeterSequence has a ._weight attribute, but it is not used here

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a.getLevelWeight()
        [0.25, 0.25, 0.25, 0.25]

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b.getLevelWeight(0)
        [0.25, 0.25, 0.25, 0.25]

        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b.getLevelWeight(0)
        [0.25, 0.25, 0.25, 0.25]

        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
        >>> b.getLevelWeight(0)
        [0.25, 0.25, 0.25, 0.25]
        >>> b.getLevelWeight(1)
        [0.25, 0.125, 0.125, 0.25, 0.125, 0.125]
        >>> b.getLevelWeight(2)
        [0.25, 0.125, 0.125, 0.25, 0.0625, 0.0625, 0.125]
        )r   r   r   )r   r  r   r   s       r    getLevelWeightzMeterSequence.getLevelWeight  s3    8 ##E*BKK		" +r"   c                    | j                  |      }t        t        |            D ]  }||   }||t        |      z     |_         y)ac  
        The `weightList` is an array of weights to be applied to a
        single level of the MeterSequence.

        >>> a = meter.MeterSequence('4/4', 4)
        >>> a.setLevelWeight([1, 2, 3, 4])
        >>> a.getLevelWeight()
        [1, 2, 3, 4]

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b.setLevelWeight([2, 3])
        >>> b.getLevelWeight(0)
        [2, 3, 2, 3]

        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b.getLevelWeight(0)
        [2, 3.0, 2, 3.0]

        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
        >>> b.getLevelWeight(0)
        [2, 3.0, 2, 3.0]
        >>> b.getLevelWeight(1)
        [2, 1.5, 1.5, 2, 1.5, 1.5]
        >>> b.getLevelWeight(2)
        [2, 1.5, 1.5, 2, 0.75, 0.75, 1.5]
        N)r   r   rv   r   )r   
weightListr  	levelObjsr   r   s         r    setLevelWeightzMeterSequence.setLevelWeight  sE    < %%e,	s9~&A1B"1s:#67BI 'r"   c                   || j                   j                  k\  s|dk  r%t        d| d| j                   j                         d}d}t        t	        |             D ]v  }|}t        || |   j                   j                  z         }|r||cxk  r|k  rn n|} |S ||cxk  r|k  rn n|} |S t        || |   j                   j                  z         }x |S )a8  
        Given an offset in quarterLengths (0.0 through self.duration.quarterLength), return
        the index of the active MeterTerminal or MeterSequence

        >>> a = meter.MeterSequence('4/4')
        >>> a.offsetToIndex(0.5)
        0
        >>> a.offsetToIndex(3.5)
        0
        >>> a.partition(4)
        >>> a.offsetToIndex(0.5)
        0
        >>> a.offsetToIndex(3.5)
        3

        >>> a.partition([1, 2, 1])
        >>> len(a)
        3
        >>> a.offsetToIndex(2.9)
        1
        >>> a[a.offsetToIndex(2.9)]
        <music21.meter.core.MeterTerminal 2/4>

        >>> a = meter.MeterSequence('4/4')
        >>> a.offsetToIndex(5.0)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: cannot access from qLenPos 5.0
            where total duration is 4.0

        Negative numbers also raise an exception:

        >>> a.offsetToIndex(-0.5)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: cannot access from qLenPos -0.5
            where total duration is 4.0
        r   cannot access from qLenPos z where total duration is )rC   rD   r   r   rv   r   )r   qLenPosincludeCoincidentBoundariesqPosmatchr   r  r  s           r    offsetToIndexzMeterSequence.offsetToIndex  s    J dmm111Wq[ -gY 7++/==+F+F*GI 
 s4y!AEQ 0 0 > >>?C*G*s*E 	 G)c)E $a!1!1!?!??@D " r"   c                6   || j                   j                  k\  s|dk  rt        d|       d}d}g }d}t        t	        |             D ]  }|}t        || |   j                   j                  z         }|r!||cxk  r|k  r7n n4|j                  |        nH||cxk  r|k  rn n|j                  |        n't        || |   j                   j                  z         } |9t        | |   t              r&t        ||z
        }|| |   j                  ||      z  }|S )a  
        Give a list of values that show all indices necessary to access
        the exact terminal at a given qLenPos.

        The len of the returned list also provides the depth at the specified qLen.

        >>> a = meter.MeterSequence('3/4', 3)
        >>> a[1] = a[1].subdivide(4)
        >>> a
        <music21.meter.core.MeterSequence {1/4+{1/16+1/16+1/16+1/16}+1/4}>
        >>> len(a)
        3
        >>> a.offsetToAddress(0.5)
        [0]
        >>> a[0]
        <music21.meter.core.MeterTerminal 1/4>
        >>> a.offsetToAddress(1.0)
        [1, 0]
        >>> a.offsetToAddress(1.5)
        [1, 2]
        >>> a[1][2]
        <music21.meter.core.MeterTerminal 1/16>
        >>> a.offsetToAddress(1.99)
        [1, 3]
        >>> a.offsetToAddress(2.5)
        [2]
        r   r  N)
rC   rD   r   r   rv   r   r   rI   r9   offsetToAddress)	r   r  r  r  r  r  r   r  qLenPosShifts	            r    r!  zMeterSequence.offsetToAddressU  s   8 dmm111Wq[ #>wi!HIIs4y!AEQ 0 0 > >>?C*G*s*LLOG)c)LLO$a!1!1!?!??@D " =ZQ? "'E/2LT!W,,\-HJ JE r"   c                   t        |      }|| j                  j                  k\  s|dk  rC|s(t        d| d| j                  j                   d|        || j                  j                  z  }| j	                  |      }d}d}d}t        t        |             D ]T  }||k(  r(|}t        || |   j                  j                  z         }0t        || |   j                  j                  z         }V ||fS )a  
        Given a qLenPos, return the span of the active region.
        Only applies to the top most level of partitions

        If `permitMeterModulus` is True, quarter length positions
        greater than the duration of the Meter will be accepted
        as the modulus of the total meter duration.

        >>> a = meter.MeterSequence('3/4', 3)
        >>> a.offsetToSpan(0.5)
        (0, 1.0)
        >>> a.offsetToSpan(1.5)
        (1.0, 2.0)

        This is the same as 1.5:

        >>> a.offsetToSpan(4.5, permitMeterModulus=True)
        (1.0, 2.0)

        Make sure it works for tuplets even with so-so rounding:

        >>> a.offsetToSpan(4.33333336, permitMeterModulus=True)
        (1.0, 2.0)

        r   cannot access qLenPos  when total duration is  and ts is N)r   rC   rD   r   r  r   rv   )r   r  permitMeterModulusiMatchr  r  r  r   s           r    offsetToSpanzMeterSequence.offsetToSpan  s    4 /dmm111Wq[% %,WI5M}}223;tfF   ; ;;G ##G,s4y!AF{S47#3#3#A#AABS47#3#3#A#AAB " czr"   c                    t        |      }|| j                  j                  k\  s|dk  r(t        d| d| j                  j                   d|        | j	                  |      }t        | |   j
                        S )a$  
        Given a lenPos, return the weight of the active region.
        Only applies to the top-most level of partitions

        >>> a = meter.MeterSequence('3/4', 3)
        >>> a.offsetToWeight(0.0)
        Fraction(1, 3)
        >>> a.offsetToWeight(1.5)
        Fraction(1, 3)

        r   r$  r%  r&  )r   rC   rD   r   r  r   )r   r  r(  s      r    offsetToWeightzMeterSequence.offsetToWeight  s     /dmm111Wq[ (	1I==../{4&B  ##G,d6l))**r"   c                   t        |      }|| j                  j                  k\  s|dk  rt        d|       d}| j	                  | j
                  dz
        }| j                  | j
                  dz
        }||j                  |      }||   \  }}|dk(  rt        |      }	n|}	d}
t        | j
                        D ]6  }| j	                  |      }|D ]  \  }}|dv r|}n|dk(  r|}||	k(  s|
dz  }
  8 |
S )ae  
        Given a qLenPos, return the maximum available depth at this position.  Align can be
        start, quantize, or end.

        >>> b = meter.MeterSequence('4/4', 4)
        >>> b[1] = b[1].subdivide(2)
        >>> b[3] = b[3].subdivide(2)
        >>> b[3][0] = b[3][0].subdivide(2)
        >>> b
        <music21.meter.core.MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
        >>> b.offsetToDepth(0)
        3
        >>> b.offsetToDepth(0.25)  # quantizing active by default
        3
        >>> b.offsetToDepth(1)
        3
        >>> b.offsetToDepth(1.5)
        2

        >>> b.offsetToDepth(-1)
        Traceback (most recent call last):
        music21.exceptions21.MeterException: cannot access from qLenPos -1.0

        * Changed in v7: `index` can be provided, if known, for a long
          `MeterSequence` to improve performance.
        r   r   r   quantize)r  r.  r  )	r   rC   rD   r   r  r]   r   r  r   )r   r  alignindexsrcMatchmapMinmsMinqStartunused_qEndposMatchscorer  r  r  r  s                  r    offsetToDepthzMeterSequence.offsetToDepth  s   8 /dmm111Wq[ #>wi!HII ""4::>2djj1n-=''0E$UmJf~HH4::&E''.G%
s11$He^"Hx'QJE & ' r"   )NN)rL   zDstr | MeterTerminal | Sequence[MeterTerminal] | Sequence[str] | Nonerp   zt.Any | Noner*   )rx   r0   r_   r   )rx   r0   rL   r   )r_   None)rL   zMeterTerminal | strr_   r9  )r_   ztools.MeterOptions)T)r;   r0   r   boolr_   r9  )r@   zSequence[int] | Sequence[str]r_   r9  )r4   r9   r_   r9  )F)rL   zMint | Sequence[str] | Sequence[MeterTerminal] | Sequence[int] | MeterSequencer_   r9  )r   
int | Noner_   r9  )NT)NFN)rL   z=str | MeterTerminal | Sequence[MeterTerminal] | Sequence[str]rp   zTint | Sequence[str] | Sequence[MeterTerminal] | Sequence[int] | MeterSequence | Noner7   r:  r8   zint | float | None)r_   r^   )rL   r^   r_   r9  )r_   r9   )r  r0   r  r:  r_   zlist[MeterTerminal])r   T)r   ra   )r.  N)r  r   r/  r+   r0  r;  )-rb   rc   rd   re   rf   r!   r(   ry   r|   r~   r   r1   rg   r   r   r   r   r   r?   r   r   r   r   r   r   r:   r   r   rh   r   r   r   r]   r  r   r   r  r  r  r  r!  r)  r+  r8  __classcell__)r$   s   @r    r9   r9     s   I W['+/S/ %/:@
$
%
$ "D1  0""0"LN"`Q"f"@ <O\<O 
	<O|b"H1f BF7;e"T -( -(r +/ %,0W"QW"!'W" W" *W"r( 6 6p ]]9 9,2h'R    " +, -dHT=*8B!8L<|9v4l+,8 8r"   r9   __main__) re   
__future__r   collections.abcr   rr   typingr   music21r   music21.common.numberToolsr   music21.common.objectsr   music21.common.typesr   music21.durationr	   r
   r   music21.exceptions21r   music21.meterr   r   EnvironmentrW   ProtoM21Objectr   r9   rb   mainTestr\   r"   r    <module>rK     s    # $    - 5 + 8  /  &{&&|4]G**,> ]FNM Nb4 zG r"   