
    rh5                   2   S r SSKJr  SSKJr  SSKrSSKrSSKJ	r	  SSK
Jr  SSKJr  SSKJr  SS	KJrJr  SS
KJr  SSKJr  SSKJr  \R.                  " S5      r " S S\	R2                  \5      r " S S\5      r\S:X  a  SSKr\R:                  " 5         gg)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)prebase)opFrac)SlottedObjectMixin)common)DurationDurationException)environment)MeterException)toolsz
meter.corec                  p   \ rS rSrSrSrSSS jjrSS jrS rS r	S	 r
SS
 jrS rSS jr  SS jr\SS j5       r\R"                  SS j5       r\SS j5       r\R"                  S S j5       r\SS j5       r\R"                  S S j5       rS r\S 5       r\R"                  S!S j5       r\S 5       rSrg)"MeterTerminal#   a  
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                    S U l         SU l        SU l        SU l        S U l        Ub8  [
        R                  " U5      nUR                  U l        UR                  U l        U R                  5         X l        g )Nr      )
r   r   r   r   r   r   slashToTuple	numeratordenominator_ratioChanged)selfslashNotationweightvaluess       L/home/james-whalen/.local/lib/python3.13/site-packages/music21/meter/core.py__init__MeterTerminal.__init__<   so     )- !""#26 $ ''6F$..DO & 2 2D
     c                    U R                  5       nU R                  Ul        U R                  Ul        UR                  5         U R                  Ul        U$ )z
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__MeterTerminal.__deepcopy__U   sE     nn,,ll
r#   c                    [        U 5      $ N)strr   s    r    _reprInternalMeterTerminal._reprInternali   s    4yr#   c                    [        [        U R                  5      5      S-   [        [        U R                  5      5      -   $ )N/)r-   intr   r   r.   s    r    __str__MeterTerminal.__str__l   s0    3t~~&'#-C8H8H4I0JJJr#   c                v    Uc  gUR                   U R                   :X  a  UR                  U R                  :X  a  gg)aY  
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    
ratioEqualMeterTerminal.ratioEqualo   s6      =OOt~~-%%)9)99r#   c                P    [        5       nUR                  XSU R                  S9  U$ )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    subdivideByCountMeterTerminal.subdivideByCount   s)    B _ 	t$++N	r#   c                ^    [        5       nUR                  U 5        UR                  U5        U$ )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.
)r>   r?   partitionByList)r   numeratorListrA   s      r    subdivideByListMeterTerminal.subdivideByList   s*    H _

=)	r#   c                    [        5       nUR                  R                  U R                  R                  :w  a  [        SU 35      eUR	                  U5        U$ )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: )r>   durationquarterLengthr   r?   )r   r8   rA   s      r    subdivideByOtherMeterTerminal.subdivideByOther   sJ    " _>>''4==+F+FF #>ug!FGG
	r#   c                   [         R                  " U5      (       a  U R                  U5      $ [        U[        5      (       a  U R                  U5      $ [         R                  " U5      (       a  U R                  U5      $ [        SU 35      e)a)  
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   
isListLikerG   
isinstancer>   rL   isNumrB   r   r   values     r    	subdivideMeterTerminal.subdivide   sw     U##''..}--((//\\%  ((// #EeW!MNNr#   c                    U R                   $ )zu
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   MeterTerminal.weight  s     ||r#   c                    Xl         g r,   rX   rS   s     r    r   rY     s    r#   c                    U R                   $ )z
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   MeterTerminal.numerator  s     r#   c                0    Xl         U R                  5         g r,   )r   r   rS   s     r    r   r\   +  s    r#   c                    U R                   $ )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   MeterTerminal.denominator0  s    $    r#   c                t    U[         R                  ;  a  [        SU 35      eXl        U R	                  5         g )Nzbad denominator value: )r   validDenominatorsSetr   r   r   rS   s     r    r   r_   D  s7     222 #:5'!BCC!r#   c                    [        5       U l         SU R                  -  U R                  -  U R                  l        g! [
         a0    [        R                  SSU R                  U R                  /5         gf = f)z9
If ratio has been changed, call this to update duration
g      @zDurationException encounteredznumerator/denominatorN)r	   r   r   r   rK   r
   environLocal
printDebugr.   s    r    r   MeterTerminal._ratioChangedL  so     "	t~~%)9)99 NN( ! 	##0(!!	s   += 7A76A7c                T    U R                   (       a  U R                   $ U R                  $ )z
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    rJ   MeterTerminal.durationa  s#    " ##+++>>!r#   c                    Xl         g r,   )r   rS   s     r    rJ   rg   w  s    #( r#   c                    g)zQ
Return how many levels deep this part is -- the depth of a terminal is always 1
r    r.   s    r    depthMeterTerminal.depth{  s    
 r#   )Nr   )r   z
str | Noner   int | floatr,   )r8   z'music21.meter.MeterSequence')rT   z)Sequence[int | str] | MeterSequence | int)returnfloat | int)rT   ro   rn   r3   )rT   r3   )rT   r	   )__name__
__module____qualname____firstlineno____doc__	__slots__r!   r)   r/   r4   r9   rB   rG   rL   rU   propertyr   setterr   r   r   rJ   rk   __static_attributes__rj   r#   r    r   r   #   s   I2(K4&P'R0O8O2 	 	 ]]      ! !&  * " "* __) )  r#   r   c                  (  ^  \ rS rSrSrSr  S.   S/U 4S jjjrS0S jrS1S jrS r	S r
S2S	 jrS
 r\S 5       rS3S jrS4S jrS5S jrS6S7S jjrS8S jrS9S jr S:   S;S jjrS0S<S jjrS r  S=S jr\S 5       r   S>       S?S jjrS r\S@S j5       r\R:                  SAS j5       rS r\S 5       rSBS jr \S 5       r!\S 5       r"S S!.S" jr#S6SCS# jjr$SDS$ jr%SES% jr&SES& jr'SES' jr(S:SFS( jjr)S:S) jr*S:S* jr+S+ r,SGSHS, jjr-S-r.U =r/$ )Ir>   i  zG
A meter sequence is a list of MeterTerminals, or other MeterSequences
)_levelListCache
_partitionparenthesissummedNumeratorc                   > [         TU ]  5         SU l        SU l        / U l        0 U l        SU l        SU l        Ub  U R                  X5        g g )Nr   r   F)	superr!   r   r   r|   r{   r~   r}   r?   )r   rT   partitionRequestr%   s      r    r!   MeterSequence.__init__  sY    
 	 !"=?LN &+ "'IIe. r#   c                <   U R                  5       nU R                  Ul        U R                  Ul        [        R                  " U R
                  U5      Ul        UR                  5         U R                  Ul        U R                  Ul        U R                  Ul	        U$ )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deepcopyr|   r   r   r~   r}   r&   s      r    r)   MeterSequence.__deepcopy__  s{    " nn,,t= #'":":"22**
r#   c                \    [        U5      [        U 5      :  a  [        eU R                  U   $ )zu
Get an MeterTerminal (or MeterSequence) from _partition

>>> a = meter.MeterSequence('4/4', 4)
>>> a[3].numerator
1
)abslen
IndexErrorr|   )r   keys     r    __getitem__MeterSequence.__getitem__  s)     s8s4y s##r#   c                ,    [        U R                  5      $ )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>
)iterr|   r.   s    r    __iter__MeterSequence.__iter__  s     DOO$$r#   c                ,    [        U R                  5      $ )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
)r   r|   r.   s    r    __len__MeterSequence.__len__  s     4??##r#   c                    [        U[        5      (       d  [        SSU 3-   5      eUR                  X   5      (       a  X R                  U'   O[        SU SX    35      e0 U l        g)a9  
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
z3values in MeterSequences must be MeterTerminals or zMeterSequences, not zcannot insert z into space of N)rQ   r   r   r9   r|   r{   )r   r   rT   s      r    __setitem__MeterSequence.__setitem__  sv    . %// !V%9%#A"B C CDI&&#(OOC  >%	{!STT  "r#   c                &    SU R                   -   S-   $ )N{})partitionDisplayr.   s    r    r4   MeterSequence.__str__  s    T***S00r#   c                    / nU R                    H  nUR                  [        U5      5        M     SR                  U5      $ )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'
+)r|   appendr-   join)r   msgmts      r    r   MeterSequence.partitionDisplay  s5    $ //BJJs2w "xx}r#   c                     / U l         0 U l        g)zE
This will not sync with .numerator and .denominator if called alone
N)r|   r{   r.   s    r    _clearPartitionMeterSequence._clearPartition5  s     !r#   c                    [        U[        5      (       a  UnO[        U5      nU R                  R                  U5        0 U l        g)z
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)rQ   r   r|   r   r{   )r   rT   r   s      r    _addTerminalMeterSequence._addTerminal=  s<     e]++Bu%B 	r"!r#   c                (   [        U R                  5      n[        U R                  5      n/ nUR                  [	        [
        R                  " X5      5      5        UR                  [	        [
        R                  " X5      5      5        [        U5      $ )a  
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'))
)	r3   r   r   extendlistr   divisionOptionsAlgodivisionOptionsPresettuple)r   ndoptss       r    getPartitionOptions!MeterSequence.getPartitionOptionsU  si    8   !D22189:D44Q:;<T{r#   c           	     f   U R                  5       nSnU H  n[        U5      U:X  d  M  Un  O   Uc=  U(       a  U(       a  US   nO)[        SU SU R                   SU R                   S35      eU R
                  nU R                  5         U H  nU R                  U5        M     X`l        0 U l        g)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  (r2   ))	r   r   r   r   r   r   r   r   r{   )r   r@   loadDefaultr   optMatchoptr=   mStrs           r    partitionByCountMeterSequence.partitionByCount{  s    j '') C3x<'  t7$.|nBt~~>NaPTP`P`Oaabc  {{Dd# "  "r#   c           	        Sn[        US   [        5      (       a  [        5       nU H-  nUR                  [        R
                  " [        U5      5        M/     UR                  5         U R                  R                  UR                  R                  :X  a  UnGO>[        SU 35      e[        [        R
                  " [        [           U5      5      [        SS5       Vs/ s H  oPR                  U-  PM     sn;   a  [        SS5       Hz  n[        [        R
                  " [        [           U5      5      U R                  U-  :X  d  MA  / nU H&  nUR                  U SU R                   U-   35        M(     [#        U5      n  OR   OOU R%                  5       n	U	 H9  n
U
 Vs/ s H   n[        UR'                  S5      S   5      PM"     nnX:X  d  M7  U
n  O   Uc)  [        SU SU R                   SU R                    S35      eU R(                  nU R+                  5         U H  nU R                  U5        M     Xl        0 U l        gs  snf s  snf )	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   	   r2   r   r   )rQ   r-   r>   r   tcast_updateRatiorJ   rK   r   sumr   r3   ranger   r   r   r   r   splitr   r   r{   )r   rF   r   testmtStrxioptMatchInnerr   r   r   nFoundr=   r   s                 r    rE   MeterSequence.partitionByList  s   F <@ mA&,, ?D&!!!&&e"45 '}}**dmm.I.II$'?%OPPS	=12SXYZ\]S^6_S^a~~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    I"'Ic                2   U R                   UR                   :X  ak  U R                  UR                  :X  aQ  U R                  nU R                  5         U H(  nU R	                  [
        R                  " U5      5        M*     X l        O[        S5      e0 U l        g)z
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   r   r   r   r{   )r   r8   r=   r   s       r    partitionByOtherMeterSequence+MeterSequence.partitionByOtherMeterSequence   sy      NNeoo-$$(9(99;;L  "!!$--"34 &K !RSS  "r#   c                   [         R                  " U5      (       a  U R                  U5        g[        U[        5      (       a  U R                  U5        g[        U[        5      (       a  U R                  XS9  g[        SU 35      e)a=  
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   rO   N)	r   rP   rE   rQ   r>   r   r3   r   r   )r   rT   r   s      r    	partitionMeterSequence.partition=  sp    j U##  '}--..u5s##!!%!A #EeW!MNNr#   c                    Sn[        [        U 5      5       HL  nUc/  X   R                  nUS;   a  SnOUS:X  a  SnOUS;   a  US-  nOUnOUnX   R                  U5      X'   MN     0 U l        g)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   r   r   rU   r{   )r   	divisionsdivisionsLocalr   partitionNumerators        r    subdividePartitionsEqual&MeterSequence.subdividePartitionsEqual{  s    \  s4y!A *.'*;*;"%)AA%&N'1,%&N'+II%71%<N &8N!* g''7DG! "&  "r#   c                    U H  nUR                  U5        M     / nU H  nU H  nUR                  U5        M     M     0 U l        U$ )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   r{   )r   processObjListr   objpostsubs         r    _subdivideNestedMeterSequence._subdivideNested  sS    P "C((3 " !CC   "  "r#   c                   U R                  S5        Sn[        U[        5      (       a&  U R                  UR	                  S5      5        US-  nO9Uc  U R
                  nUS;   a  SnOUS;   a  SnOUnU R                  U5        US-  nU S   /nXA:  a  U R                  USS9nUS-  nU(       d  M#   / nU H0  nUR                  U;  d  M  UR                  UR                  5        M2     [        U5      S:  ae  / n	[        [        U5      5       HH  n
Xj   R                  [        U5      :X  a  XR                  Xj   /SS9-  n	M5  U	R                  Xj   5        MJ     U	nOOM  XA:  a  M  0 U l        g)	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   rQ   r>   r?   getLevelr   r   r   r   r   r   r   minr{   )r   rk   firstPartitionFormnormalizeDenominators
depthCountdivFirstr   r   refpostNewr   s              r    subdivideNestedHierarchy&MeterSequence.subdivideNestedHierarchy  s   D 	q

 (-88 II(11!45!OJ!)%)^^"!%99#s* . ))(3!OJ Qy (((>D!OJ(Ca/1   q6A: G"3t9-  7..#a&8#'<'<dgYGK (= (M MG $NN473 . #D)   >  "r#   c                ^    [        U 5      nSnU[        U5      :  a  X!   $ [        U5      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)r   r-   )r   count	countNames      r    partitionStrMeterSequence.partitionStr|  s;    L D	8	
 3y>!##u:''r#   c                   U(       a  Uc  U R                   nOSnU R                  5         [        U[        5      (       ac  [        R
                  " U5      u  oPl        U H&  u  pgU SU 3nU R                  [        U5      5        M(     U R                  5         Ub  X@l         O[        U[        5      (       a+  Ub  XAl         U R                  U5        U R                  5         O^[        R                  " U5      (       a4  U H  n	U R                  U	5        M     U R                  5         Ub  X@l         O[        SU< 35      eUb  U R                  U5        0 U l        g)a  
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}'
Nr2   z%cannot create a MeterSequence with a )r   r   rQ   r-   r   slashMixedToFractionr~   r   r   r   r   
isIterabler   r   r{   )
r   rT   r   r<   r=   	ratioListr   r   r   r   s
             r    r?   MeterSequence.load  s?   T ##{{L 	eS!!.3.H.H.O+I+!#$#Qqc
!!-">? " '*}-- '+e$ u%%!!#&  '* #H	!RSS'NN+,  "r#   c                    [        S U R                   5       5      n[        R                  " U5      u  U l        U l        U R                  5         g)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  P   #    U  H  oR                   UR                  4v   M     g 7fr,   r7   ).0r   s     r    	<genexpr>-MeterSequence._updateRatio.<locals>.<genexpr>  s     P"bnn5s   $&N)r   r|   r   fractionSumr   r   r   )r   fTuples     r    r   MeterSequence._updateRatio	  s@     PPP .3->->v-F**r#   c                L    SnU R                    H  nXR                  -  nM     U$ )a  
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.
        )r|   r   )r   	summationr   s      r    r   MeterSequence.weight  s*    j 	??C#I #r#   c                   [         R                  " U5      (       d  [        S5      e U R                  U R                  -  nU R                   H(  nUR                  UR                  -  nXU-  -  Ul        M*     g ! [
         aY    [        SSU R                  < S[        U R                  5      < SU R                  < S[        U R                  5      < 3-   5      ef = f)Nzweight values must be numbersz!Something wrong with the type of zthis numerator  z or this denominator )	r   rR   r   r   r   	TypeErrortyper|   r   )r   rT   
totalRatior   	partRatios        r    r   r  W  s     ||E"" !@AA	O4+<+<<J //B7IZ!78BI "  	O 3$t"7"&"3"3T$:K:K5LNNO O	Os   A: :A#Cc                    / nU R                    H=  n[        U[        5      (       d  UR                  U5        M+  XR	                  5       -  nM?     U$ )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
)r|   rQ   r>   r   _getFlatList)r   mtListr   s      r    r   MeterSequence._getFlatListn  sI    X ??Cc=11c"**,,	 #
 r#   c                "    U R                  5       $ )z>
deprecated.  Call .flatten() instead.  To be removed in v11.
)flattenr.   s    r    flatMeterSequence.flat  s    
 ||~r#   c                X    [        5       nUR                  U R                  5       5        U$ )aU  
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}>
)r>   r?   r   )r   r   s     r    r$  MeterSequence.flatten  s&    J 		$##%&r#   c                n    / nU R                  5        H  nUR                  UR                  5        M      U$ )z%
Return a list of flat weight values
)r   r   r   )r   r   r   s      r    
flatWeightMeterSequence.flatWeight  s1    
 ##%BKK		" &r#   c                R    SnSn U R                  U5      nX2:w  a  US-  nUnO U$ M#  )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   rk   	lastMatchr   s       r    rk   MeterSequence.depth  sB     	$$U+D 
 	 r#   r   )rk   c               (   / n/ nU R                  U5       Hy  nUR                  U;  a  UR                  UR                  5        UR                  U;  a  UR                  UR                  5        [	        U5      S:  d  [	        U5      S:  d  My    g   g)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   r   )r   rk   r   r   rA   s        r    isUniformPartition MeterSequence.isUniformPartition  sy    F ##E*B||1$&~~Q&(1vzSVaZ + r#   c                x   X4n [        [        U R                  U   5      5      $ ! [         a     Of = f/ n[	        [        U R                  5      5       H  nU R                  U   n[        U[        5      (       d  X   nUR                  U5        M>  US:  a  XFR                  US-
  U5      -  nM]  U(       aJ  [        UR                  < SUR                  < 35      nUR                  Ul        UR                  U5        M  UR                  U5        M     [        [        U5      5      U R                  U'   U$ )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   r2   )r   r   r{   KeyErrorr   r   r|   rQ   r>   r   r-  r   r   r   r   )r   
levelCountr%  cacheKeyr!  r   partition_ir   s           r    r-  MeterSequence.getLevelList   s!   R %	d228<=>> 		 ')s4??+,A7;q7IKk=99Wb!> 66"Q. .F *'11;3J3J,L M %0$6$6	b)k2) -. *.eFm)<X&s    & 
33c                6    [        U R                  X5      5      $ )ay  
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}>
)r>   r-  )r   levelr%  s      r    r   MeterSequence.getLevel  s    & T..u;<<r#   c                    U R                  USS9n/ nSn[        [        U5      5       H=  nUn[        XBU   R                  R
                  -   5      nUR                  Xg45        UnM?     U$ )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   r   r   rJ   rK   r   )r   r:  rA   mappingposr   startends           r    getLevelSpanMeterSequence.getLevelSpan  so    " u40s2wAE!u~~;;;<CNNE<(C	  
 r#   c                p    / nU R                  U5       H  nUR                  UR                  5        M      U$ )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    getLevelWeightMeterSequence.getLevelWeight  s3    8 ##E*BKK		" +r#   c                    U R                  U5      n[        [        U5      5       H  nX4   nX[        U5      -     Ul        M     g)a  
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   r   r   )r   
weightListr:  	levelObjsr   r   s         r    setLevelWeightMeterSequence.setLevelWeight  sA    < %%e,	s9~&AB"s:#67BI 'r#   c                   XR                   R                  :  d  US:  a)  [        SU S3SU R                   R                   3-   5      eSnSn[        [	        U 5      5       H}  nUn[        X0U   R                   R                  -   5      nU(       a  Xas=::  a  U::  a  O  OUn  U$ OXas=::  a  U:  a  O  OUn  U$ [        X0U   R                   R                  -   5      nM     U$ )aH  
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 r  zwhere total duration is )rJ   rK   r   r   r   r   )r   qLenPosincludeCoincidentBoundariesqPosmatchr   r?  r@  s           r    offsetToIndexMeterSequence.offsetToIndex"  s    J mm111Wq[ -gYa8,T]]-H-H,IJK 
 s4y!AEQ 0 0 > >>?C**s*E  + )c)E $a!1!1!?!??@D " r#   c                   XR                   R                  :  d  US:  a  [        SU 35      eSnSn/ nSn[        [	        U 5      5       H  nUnX@U   R                   R                  -   nU(       a#  X1s=::  a  U::  a  O  O6UR                  U5          OBO"X1s=::  a  U:  a  O  OUR                  U5          OX@U   R                   R                  -  nM     Ub2  [        X   [        5      (       a  X-
  nXPU   R                  UU5      -  nU$ )aX  
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   rL  N)	rJ   rK   r   r   r   r   rQ   r>   offsetToAddress)	r   rN  rO  r?  rP  rQ  r   r@  qLenPosShifts	            r    rU  MeterSequence.offsetToAddress`  s
   8 mm111Wq[ #>wi!HIIs4y!AEa))777C**s*LLO + )c)LLOG$$222D " =Z?? #?L!W,,\-HJ JE r#   c                   [        U5      nXR                  R                  :  d  US:  aJ  U(       d+  [        SU< SU R                  R                  < SU < 35      eXR                  R                  -  nU R	                  U5      nSnSnSn[        [        U 5      5       HT  nXs:X  a(  Un[        X@U   R                  R                  -   5      nM0  [        X@U   R                  R                  -   5      nMV     XV4$ )aJ  
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   rJ   rK   r   rR  r   r   )r   rN  permitMeterModulusiMatchr>  r?  r@  r   s           r    offsetToSpanMeterSequence.offsetToSpan  s    6 /mm111Wq[% %!<!<dDE E
  ; ;;G ##G,s4y!A{S7#3#3#A#AABS7#3#3#A#AAB " zr#   c                    [        U5      nXR                  R                  :  d  US:  a+  [        SU< SU R                  R                  < SU < 35      eU R	                  U5      n[        X   R
                  5      $ )z
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   rY  rZ  r[  )r   rJ   rK   r   rR  r   )r   rN  r]  s      r    offsetToWeightMeterSequence.offsetToWeight  sn     /mm111Wq[ T]]88$@A A ##G,dl))**r#   c                   [        U5      nXR                  R                  :  d  US:  a  [        SU 35      eSnU R	                  U R
                  S-
  5      nU R                  U R
                  S-
  5      nUc  UR                  U5      nXS   u  pxUS:X  a  [        U5      n	OUn	Sn
[        U R
                  5       H<  nU R	                  U5      nU H"  u  pUS;   a  UnOUS:X  a  UnXI:X  d  M  U
S-  n
M$     M>     U
$ )a  
Given a qLenPos, return the maximum available depth at this position.

>>> 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   rL   r   quantize)r?  re  r@  )	r   rJ   rK   r   rA  rk   r   rR  r   )r   rN  alignindexsrcMatchmapMinmsMinqStartunused_qEndposMatchscorer:  r=  r?  r@  s                  r    offsetToDepthMeterSequence.offsetToDepth  s   4 /mm111Wq[ #>wi!HII ""4::>2djj1n-=''0E$mJf~HH4::&E''.G%
11$He^"H'QJE & ' r#   )r   r{   r   r|   r}   r~   r   )NN)rT   zDstr | MeterTerminal | Sequence[MeterTerminal] | Sequence[str] | Noner   zt.Any | Noner,   )r   r3   rn   r   )r   r3   rT   r   )rn   None)rT   zMeterTerminal | strrn   rq  )rn   ztools.MeterOptions)T)r@   r3   r   boolrn   rq  )rF   zSequence[int] | Sequence[str]rn   rq  )r8   r>   rn   rq  )F)rT   zMint | Sequence[str] | Sequence[MeterTerminal] | Sequence[int] | MeterSequencern   rq  )r   
int | Nonern   rq  )NT)NFN)rT   z=str | MeterTerminal | Sequence[MeterTerminal] | Sequence[str]r   zTint | Sequence[str] | Sequence[MeterTerminal] | Sequence[int] | MeterSequence | Noner<   rr  r=   zint | float | None)rn   rm   )rT   rm   rn   rq  )rn   r>   )r5  r3   r%  rr  rn   zlist[MeterTerminal])r   T)r   rp   )re  N)rg  rs  )0rq   rr   rs   rt   ru   rv   r!   r)   r   r   r   r   r4   rw   r   r   r   r   r   rE   r   r   r   r   r   r  r?   r   r   rx   r   r%  r$  r*  rk   r1  r-  r   rA  rD  rI  rR  rU  r^  ra  ro  ry   __classcell__)r%   s   @r    r>   r>     s   I W['+/S/ %/ /:@
$
%
$ "D1  0""0"LO"bR"h"@ <O\<O 
	<O|b"H1f BF7;e"T .( .(t +/ %,0W"QW"!'W" W" *W"r( 7 7r ]]9 9,2h  'R    " +, -dHT=*8B!8L<|9v4l+*6 6r#   r>   __main__)ru   
__future__r   collections.abcr   r   typingr   music21r   music21.common.numberToolsr   music21.common.objectsr   r   music21.durationr	   r
   r   music21.exceptions21r   music21.meterr   Environmentrc   ProtoM21Objectr   r>   rq   mainTestrj   r#   r    <module>r     s    # $    - 5  8  / &&|4]G**,> ]FVM Vr4 z r#   