
    3jT                    H   U d Z ddlmZ ddlZddl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 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 ddlmZ  ej*                  d      Z G d de	j.                        Z G d dej2                        Z G d de	j.                        Z G d d      Z G d de	j.                        Z G d d      Z G d dej>                        Z  G d dej>                        Z!g Z"d e#d!<   e$d"k(  rddlZ ejJ                  e        yy)#z
Tools for generation reduction displays, showing a score and or a chord reduction,
and one or more reductive representation lines.

Used by graph.PlotHorizontalBarWeighted()
    )annotationsN)exceptions21)chord)common)DocOrder)environment)expressions)
instrument)note)pitch)prebase)streamzanalysis.reductionc                      e Zd Zy)ReductiveEventExceptionN__name__
__module____qualname__     G/DATA/.local/lib/python3.12/site-packages/music21/analysis/reduction.pyr   r   )       r   r   c            	      h    e Zd ZdZdZdZdddddd	d
ddZdddddddZd Zd Z	d Z
ddZddZd Zy)ReductiveNotea  
    The extraction of an event from a score and specification of where
    and how it should be presented in a reductive score.

    A specification string, as well as Note, must be provided for parsing.

    A specification must be created when access the Measure that the source note
    is found in. Storing the measure and index position provides significant
    performance optimization, as we do no have to search
    every note when generated the reduction.

    The `measureIndex` is the index of measure where this is found, not
    the measure number. The `measureOffset` is the position in the measure
    specified by the index.
    :/r   octavenoteheadFillstemDirectiongroupvoice	textAbove	textBelow)ponfsdgvtatbNnoStem)r   r   r   r   r    r!   c                    || _         d | _        i | _        d| _        | j	                  | j                          || _        || _        || _        y )NF)_specification_note_parameters	_isParsed_parseSpecificationmeasureIndexmeasureOffset)selfspecification	inputNoter3   r4   s        r   __init__zReductiveNote.__init__X   sK    +
  !4!45
(*r   c                   g }| j                   D ]p  }| j                   |   }|| j                  v s!| j                  |   s1|j                  |       |j                  d       |j                  | j                  |          r | j                  5|j                  d       |j                  t	        | j                               dj                  |      S )Nr   z of  )_parameterKeysr0   appendr/   reprjoin)r5   msgkeyattrs       r   _reprInternalzReductiveNote._reprInternald   s    &&C&&s+Dt'''##D)JJsOJJsOJJt//56 ' ::!JJvJJtDJJ'(wws|r   c                     | j                   |   S N)r0   )r5   r@   s     r   __getitem__zReductiveNote.__getitem__r   s    $$r   c                &   t        j                  | j                        | _        |j	                         }|j                  | j                  | j                  z         sy |j                  | j                        }|dd  D ]  }| j                  |vr|j                  | j                        \  }}|j	                         }|j	                         }|j                         | j                  v sm| j                  |   }|| j                  |<    d| _        y )N   T)copydeepcopy_defaultParametersr0   strip
startswith_delimitValuesplit_delimitArglowerr;   r1   )r5   specargsacandidateKeyvaluerA   s          r   r2   z!ReductiveNote._parseSpecificationu   s    ==)@)@Azz|t11D4F4FFGzz$**+abA!!*"#''$*<*<"=L%'--/LKKME!!#t':'::**<8).  &  r   c                    | j                   S rD   )r1   r5   s    r   isParsedzReductiveNote.isParsed   s    ~~r   c                   d}| j                   j                  rd| j                  v rt        j                  | j                  d         }| j                   D ]W  }|j
                  j                         |j                  j
                  j                         k(  sCt        j                  |      }Y nLt        j                  | j                   j                  d         }nt        j                  | j                         }|*| j                  d   }t        d|d| j                         g |_        d|_        g |_        g |_        d|j                  _        |j                  j"                  d|j                  j"                  _        d}d| j                  v r-| j                  d   r| j                  d   |j                  _        d| j                  v r| j                  d   |_        d	| j                  v r'| j                  d	   }|r|d
k(  rd}n|dk(  rd}||_        d| j                  v r|j-                  | j                  d          d| j                  v r"t        j.                  | j                  d         }||fS )zt
        Produce a new note, a deep copy of the supplied note
        and with the specified modifications.
        Nr   r   zCould not find pitch, z in self._note: Tr   r   r   yesnoFr#   r"   )r/   isChordr0   r   PitchnamerP   rH   rI   pitchesr   lyricstier	   articulationsdurationdots
accidentaldisplayStatusr   r   r   addLyricTextExpression)r5   nr$   subpitchParametertenhfs          r   getNoteAndTextExpressionz&ReductiveNote.getNoteAndTextExpression   s   
 ::$***KK 0 0 9:::Cvv||~)=)=)?? MM#. & MM$**"4"4Q"78djj)A9!--g6N)((::J4::.Y[ [

77)/3AGG,t''')!%!1!1(!;d..."..?AOT---"">2C%<CD[C!$$***JJt''45$***++D,<,<[,IJB"ur   )rQ   str)returnbool)r   r   r   __doc__rM   rO   r;   rJ   r8   rB   rE   r2   rX   rn   r   r   r   r   r   2   sn     MK 	N !
+%(3r   r   c                      e Zd Zy)ScoreReductionExceptionNr   r   r   r   rt   rt      r   r   rt   c                  |    e Zd ZdZd Zd Zd Z eeed      Zd Z	d Z
 ee
e	d	      Zdd
ZddZd Zd Zd Zy)ScoreReductionz&
    An object to reduce a score.
    c                J    i | _         g | _        g | _        d | _        d | _        y rD   )_reductiveNotes_reductiveVoices_reductiveGroups_score_chordReduction)r5   keywordss     r   r8   zScoreReduction.__init__   s+    ! " " #r   c                V   t        |t        j                        st        d      |j                  rt        j                  |      | _        n@t        j                         }|j                  dt        j                  |             || _        | j                  j                  dd       y )Ncannot set a non Streamr   rv   T)recurse)
isinstancer   Streamrt   hasPartLikeStreamsrH   rI   r{   ScoreinsertsetDerivationMethodr5   rU   ss      r   	_setScorezScoreReduction._setScore   sv    %/)*CDD##--.DKAHHQe,-DK''(8$'Gr   c                    | j                   S rD   )r{   rW   s    r   	_getScorezScoreReduction._getScore   s    {{r   z
        Get or set the Score. Setting the score set a deepcopy of the score; the score
        set here will not be altered.

        >>> s = corpus.parse('bwv66.6')
        >>> sr = analysis.reduction.ScoreReduction()
        >>> sr.score = s
        )docc                $   t        |t        j                        st        d      |j	                         rt        j                  |      | _        y t        j                         }|j                  dt        j                  |             || _        y )Nr   r   )
r   r   r   rt   r   rH   rI   r|   r   r   r   s      r   _setChordReductionz!ScoreReduction._setChordReduction   sc    %/)*CDD##%#'==#7D AHHQe,-#$D r   c                    | j                   S rD   )r|   rW   s    r   _getChordReductionz!ScoreReduction._getChordReduction   s    ###r   z
        Get or set a Chord reduction as a Stream or Score. Setting the this values
        set a deepcopy of the reduction; the reduction set here will not be altered.
        c                    |y|j                   D ]j  }t        |j                  t        j                              D ]=  \  }}|j                         j                  D ]  }|||d}| j                  |||        ? l y)zm
        Remove and store all reductive events
        Store in a dictionary where obj id is obj key
        Npartmeasurer3   )parts	enumerategetElementsByClassr   Measurer   notes_extractNoteReductiveEvent)r5   scoreremoveAfterParsingr$   imri   infoDicts           r   _extractReductionEventsz&ScoreReduction._extractReductionEvents  sx    
 =A!!"6"6v~~"FG1**A()+,01 3H 33AxAST	 + H r   Nc                &   |d d dd}|d   }|j                   sy g }||v r|j                  |      }n)d}|j                  D ]  }||v s|j                  |      } t        |j                         D ]r  \  }}	t	        |	j
                  ||d   |      }
|
j                         s2t        t        |            |	j
                  z   }|
| j                  |<   |j                  |       t |r*|D ]$  }t        j                  d      |j                   |<   & y y )Nr   r   r           r3   r:   )r`   getOffsetBySitevoicesr   r   textrX   ro   idrx   r<   r   Lyric)r5   ri   r   r   r   removalIndicesoffsetr)   klyrrnr@   qs                r   r   z)ScoreReduction._extractNoteReductiveEvent  s    $#'()H Yxx6&&q)FFXX6..q1F   )FAssxxH^,DfMB{{} "Q%j388+,.$$S)%%a( * #"jjn $ r   c                   i | _         | j                  | j                         | j                  | j                         | j                   j	                         D ]  \  }}|d   | j
                  vr| j
                  j                  |d          |d   | j                  vr| j                  j                  |d          t        | j
                        dk(  r)d | j
                  v r| j
                  j                  d        t        | j                        dk(  sd | j                  v s| j                  j                  d         y )Nr    r!      )
rx   r   r|   r{   itemsrz   r<   ry   lenremove)r5   
unused_keyr   s      r   _parseReductiveNotesz#ScoreReduction._parseReductiveNotes9  s   !$$T%9%9:$$T[[1"2288:NJ'{$"7"77%%,,R[9'{$"7"77%%,,R[9 D))*a/ 5 55%%,,T2 D))*a/ 5 55%%,,T2 ;r   c                   | j                          t        j                         }d}t        | j                        dk(  rd}d}t        | j
                        dk(  rd}| j                  r5| j                  j                  j                         j                  d      }n4| j                  j                  j                         j                  d      }| j                  D ]  }t        j                  |      }||_        t        j                         }||_        |j#                  d|       |j%                  t        j&                        }| j(                  j+                         D ]M  \  }	}
|s	|
d   |k(  s||
j,                     }|j.                  sO|j1                  d       | j
                  D ]/  }t        j2                         }||_        |j#                  d|       1 |r\|
j5                         \  }}|j.                  d   j7                  |
j8                  |       |s|j#                  |
j8                  |       |j;                  |
d         }||j.                  d   }|
j5                         \  }}|j7                  |
j8                  |       |s2|j#                  |
j8                  |       P t=        |j%                  t        j&                              D ]  \  }}|j.                  D ]0  }|j?                         j@                  s|jC                  dd	       2 |jE                  d
       |tF        jH                     D ]  }d|jJ                  _&          |j#                  d|        | j                  r-| j                  j                  D ]  }|j#                  d|        g }| j                  r>| j                  j                  D ]%  }|j#                  d|       |jO                  |       ' |S )NFrG   T)retainVoicesr   r    Restr!   )fillGapsinPlacer   )(r   r   r   r   rz   ry   r{   r   firsttemplater|   rH   rI   r   r
   
InstrumentpartNamer   r   r   rx   r   r3   r   removeByClassVoicern   insertIntoNoteOrChordr4   getElementByIdr   r   r   	makeRestsflattenUnnecessaryVoicesr   r   stylehideObjectOnPrintr<   )r5   r   oneGrouponeVoice	mTemplategNamer(   inst	gMeasuresr   r   gMeasurevIdr)   ri   rl   r   r   rr$   srcPartss                        r   _createReductionzScoreReduction._createReductionO  sG   !!#LLNt$$%*Ht$$%*H;;))//1:::NI,,2288:CCQVCWI **E i(AAD((*D!DMHHQ,,V^^<I
 #'"6"6"<"<">
Br'{e3  )9H#?? ..v6#'#8#8C &A#&AD$OOAq1 $9   " ; ; =2 *@@,,a1 $OOB,<,<bA$33BwK@9 ( 2A " ; ; =2//0@0@!D$OOB,<,<bA5 #?: "!"6"6v~~"FG1Ayy{((T4@ " **4*8499A04AGG- & H HHQNk +p ))//A 0 ;;[[&&A" ' r   c                h    | j                   | j                  t        d      | j                         S )z>
        Given a score, populate this Score reduction
        zno score defined to reduce)r   chordReductionrt   r   rW   s    r   reducezScoreReduction.reduce  s4    
 ::$"5"5"=)*FGG$$&&r   )T)NT)r   r   r   rr   r8   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   rv   rv      sk    $
H Y	 0 E	%$ 02D K NU "-J3,Tl'r   rv   c                      e Zd Zy)PartReductionExceptionNr   r   r   r   r   r     r   r   r   c                  p    e Zd ZdZ	 ddddddd	 	 	 	 	 	 	 	 	 ddZd Zd Z	 	 	 dd	Zd
 ZddZ	d Z
d Zy)PartReductiona  
    A part reduction reduces a Score into one or more parts.
    Parts are combined based on a part group dictionary.
    Each resulting part is then segmented by an object.
    This object is assigned as floating-point value.

    This reduction is designed to work with the GraphHorizontalBarWeighted and related Plot
    subclasses.

    If the `fillByMeasure` parameter is True, and if measures are available,
    each part will segment by Measure divisions, and look for the target activity only
    once per Measure.

    If more than one target is found in the Measure, values will be averaged.

    If `fillByMeasure` is False, the part will be segmented by each Note.

    The `segmentByTarget` parameter is True, segments, which may be Notes or Measures,
    will be divided if necessary to show changes that occur over the duration of the
    segment by a target object.

    If the `normalizeByPart` parameter is True, each part will be normalized within
    the range only of that part. If False, all parts will be normalized by the max
    of all parts. The default is True.

    If the `normalize` parameter is False, no normalization will take place. The default is True.

    NTF)
partGroupsfillByMeasuresegmentByTarget	normalizenormalizeByPartc               ,   |y t        |t        j                        st        d      || _        g | _        i | _        || _        || _        || _	        || _
        || _        | j                  j                  D ]  }|j                         rd| _         y  y )Nzprovided Stream must be ScoreF)r   r   r   r   r{   _partBundles_eventSpans_partGroups_fillByMeasure_segmentByTarget_normalizeByPart_normalizeToggler   hasMeasures)	r5   srcScorer   r   r   r   r   r}   r$   s	            r   r8   zPartReduction.__init__  s     (FLL1()HII 5779 &+ !0 / ) ""A==?&+#	 #r   c                   g | _         | j                  r| j                  D ]  }|d   |d   |d   }}}g }| j                  j                  D ]  }||g}t	        |j
                        j                         }|D ]}  }t        |t              r5|j                  |j                               dk\  r|j                  |        ut        j                  |j                         |      sm|j                  |         |s|||d}	| j                   j                  |	        nG| j                  j                  D ].  }|j
                  d|gd}	| j                   j                  |	       0 | j                   D ]p  }
t        |
d         d	k(  r|
d   d   j                         |
d
<   .t        j                         }|
d   D ]  }|j!                  d|        |j                         |
d
<   r y)z
        Fill the _partBundles list with dictionaries,
        each dictionary defining a name (part id or supplied), a color, and list
        of Parts that match.
        r^   colormatchNr   )pGroupIdr   r   #666666r   rG   
parts.flat)r   r   r{   r   ro   r   rP   r   findr<   rer   r   flattenr   r   r   )r5   dr^   pColormatchesrj   r$   pIdr   data
partBundler   s               r   _createPartBundlesz PartReduction._createPartBundles  s    %%()&	1W:qzgf**A #'&add)//+C$&q#.$'HHQWWY$71$<JJqM!XXaggi5JJqM % +  $# 
 !!((.1 &4 [[&&$%DD9sK!!((. ' ++J:g&'1,+5g+>q+A+I+I+K
<( MMO#G,AHHQN -+,99;
<( ,r   c                   i | _         | j                  D ]  }|d   }|d   }|d   }g }d }d }d }| j                  rg }	|D ]>  }
|	j                  |
j	                  t
        j                        j                                @ t        t        |	d               D ]  }d}|	D ]#  }
|
|   j                         j                  s!d} n |s0|	d   |   }|j                  |	d         }||j                  j                  z   }|||z
  d |d}|j                  |        n|d   }|j                         }t        |      D ]  \  }}|?||j                  |      |j                  z   }|||z
  d |d}|j                  |       d }G|t        |      d	z
  k\  rO||j                  |      }|j                  |      |j                  z   }|||z
  d |d}|j                  |       d }||j                  |      }|} || j                   |<    y )
Nr   r   r   r   FT)eStartspanweightr   r   rG   )r   r   r   r<   r   r   r   ranger   iterr   r   barDurationquarterLengthfindConsecutiveNotesr   )r5   r   r   r   r   
dataEventsr   eEndeLastpartMeasuresr$   r   activeedseSrcnoteSrcs                    r   _createEventSpanszPartReduction._createEventSpans.  sW   ++J!*-H(Fw'EJFDE ""!A ''(<(<V^^(L(S(S(UV  s<?34A"F)Q499;,,%)F!	 * " $Q*A..|A?F #Q]]%@%@@D$*"&-$(#)B
 %%b)- 5d ",/ 335%g.DAq y!>$#(#8#8#>ATAT#TD(.&*Vm(,'- 
 #))"-!%c'lQ..!>%&%6%6t%<F 006H(.&*Vm(,'- 
 #))"-!%!>%&%6%6t%<F !A /D *4DX&[ ,r   c           	        fd}||}|s| j                   D ]p  }|d   }| j                  |d      D ]T  }|d   }||d   z   }	|j                  ||	ddd	      j                        j	                         }
|
sd}n ||
      }||d
<   V r y| j                   D ]  }g }|d   }| j                  |d      D ]  }|d   }||d   z   }	|j                  ||	ddd	      j                        j	                         }
|
j                  d       t        j                  |      }|
s|j                  |       t        |
      D ]  \  }}|j                  |      }|j                  j                  }||z   |	kD  r|	|z
  }|dk  r|	|z
  }|dk(  r*|d   |k(  r"||d<    ||      |d
<   |j                  |       tt        dk(  r]|d   |k7  rU||z
  |d<   |j                  |       t        j                  |      }||d<   ||d<    ||      |d
<   |j                  |       t        j                  |      }||d<   ||d<    ||      |d
<   |j                  |         || j                  |d   <    y)a  
        For each span, determine the measured parameter value. This is translated
        as the height of the bar graph.

        If `splitSpans` is True, a span will be split of the target changes over the span.
        Otherwise, Spans will be averaged. This is the `segmentByTarget` parameter.

        The `targetToWeight` parameter is a function that takes a list or Stream of objects
        (of the class specified by `target`) and returns a single floating-point value.
        c                    t        | d      r| j                  rnt        j                  |       s| g} d}| D ]  }||j                  z  } |t              z  S )NisStreamr   )hasattrr  r   
isIterablevolumeScalarr   )targets	summationr  targets      r   _dynamicToWeightz8PartReduction._getValueForSpan.<locals>._dynamicToWeight  sY    w
+0@0@&&w/")IQ^^+	 s6{**r   Nr   r   r   r   FT)includeEndBoundarymustFinishInSpanmustBeginInSpanr   r   gMbP?r   )r   r   getElementsByOffsetr   r   extendDurationrH   rI   r<   r   r   rc   r   t)r5   r  
splitSpanstargetToWeightr  r   flatRefr  offsetStart	offsetEndr   wfinalBundledsFirstr   tartargetStart
targetSpandsNexts    `                 r   _getValueForSpanzPartReduction._getValueForSpan  s   "		+ !-N"//
$\2**:j+ABB"$X,K +bj 8I#77#!+0).(, 8  )(0  ! *51#$BxL! C 0( #//
 $\2**:j+ABB"$X,K +bj 8I $77Y+/%(, 8 ..@.@.H 
 (((>"mmB/G #**73 "+E"23&)&9&9'&B%(\\%?%?
 '3i?)2[)@J &.)2[)@J 6blk&A /9GFO0>s0CGH-'..w7!V8(C /:K.GGFO'..w7%)]]2%6F/:F8,-7F6N/=c/BF8,'..v6%)]]2%6F/:F8,-7F6N/=c/BF8,'..v6O #3% Cv <G  J!78 0r   c                    d}| j                   D ]^  }d}t        | j                  |d            D ]<  \  }}|dk(  r|d   ||d<   |d   }|d   r|d   }'|r||d<   /|d   5|8||d<   > ` y)z
        Extend the value of a target parameter to the next boundary.
        An undefined boundary will wave as its weight None.
        g{Gz?Nr   r   r   )r   r   r   )r5   minValuer   
lastWeightr   r  s         r   _extendSpanszPartReduction._extendSpans  s     ++JJ"4#3#3Jz4J#KL26(|+'/8 &(\
(|%'\
#'18H-*2D'/8 M ,r   c                t   i }| j                   D ]1  }d}| j                  |d      D ]  }|d   |kD  s|d   } |||d   <   3 	 t        |j                               }| j                   D ]<  }| j                  |d      D ]%  }|r	||d      }n|}|dk7  r|d   |z  |d<   !d|d<   ' > y# t        $ r d}Y Yw xY w)zF
        Normalize, either within each Part, or for all parts
        r   r   r   rG   N)r   r   maxvalues
ValueError)r5   byPart
partMaxRefr   partMaxr  maxOfMaxbestMaxs           r   
_normalizezPartReduction._normalize<  s     
++JG&&z*'=>h<') lG ? 29Jz*-. ,	:,,./H ++J&&z*'=>(J)?@G&Ga<$&xL7$:BxL#$BxL ? ,  	H	s   B) )B76B7c                    | j                          | j                          | j                  | j                         | j	                          | j
                  r| j                  | j                         yy)z+
        Core processing routines.
        )r  )r1  N)r   r  r(  r   r,  r   r6  r   rW   s    r   processzPartReduction.processY  sa     	! )>)>?  OO4#8#8O9 !r   c           	         g }| j                   D ]T  }g }|d   }| j                  |   D ]#  }|j                  |d   |d   |d   |d   g       % |j                  |d   |f       V |S )zF
        Get all data organized into bar span specifications.
        r   r   r   r   r   )r   r   r<   )r5   r   r   dataList
groupSpansr  s         r   !getGraphHorizontalBarWeightedDataz/PartReduction.getGraphHorizontalBarWeightedDataf  s     ++JH#J/J&&z2Hr&z2h<G UV 3 KKJ/:; , r   rD   )
r   zlist[dict[str, t.Any]] | Noner   rq   r   rq   r   rq   r   rq   )DynamicTNF)r   r   r   rr   r8   r   r  r(  r,  r6  r8  r<  r   r   r   r   r     s    : % <@'+)-#').% 9% !%	%
 #'% !% #'%N17hq4l 	tGl0H%:	:r   r   c                  \    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
dd	Zd
 Zd Zd Zd Zy)Testc                2    ddl m}  || t                      y )Nr   )testCopyAll)music21.test.commonTestrB  globals)r5   rB  s     r   testCopyAndDeepcopyzTest.testCopyAndDeepcopy|  s    7D')$r   c                
   ddl m} ddl m} |j                  d      }|j                  d   j                         j                  d   j                  d       |j                  d   j                         j                  d   j                  d       |j                  d   j                         j                  d	   j                  d
       |j                  d   j                         j                  d   j                  d       |j                  j                         }||_
        |j                         }| j                  t        |j                  d   j                         j                        d       |j                  j                         t        j                      d d }t        j"                         }|D ]  }|j%                  |        |j                         }	|	j&                  D 
cg c].  }
t)        |
      |
j*                  |
j,                  j.                  f0 }}
d | _        | j                  |g d       | j                  |j                  d   j                         j                  d   j2                  d       y c c}
w )Nr   analysiscorpusbwv66.6   test   z::/o:6/tb:herer   z::/o:5/tb:fromBassrG      z ::/o:4/nf:no/g:Ursatz/ta:3 3 200))<music21.note.Rest quarter>r         ?)z<music21.note.Note F#>rQ  rQ  )rP         @rQ  )z<music21.note.Note C#>      @rQ  )rP        @rQ  )z<music21.note.Note G#>g      @rQ  fromBass)music21rH  rJ  parser   r   r   rg   	reductionrv   r   r   assertEqualr   r   r   r   r   r<   notesAndRestsr=   r   rc   r   maxDifflyric)r5   rH  rJ  r   srpostthree_measures
new_streamr   flat_streamr  r   s               r   testExtractionAzTest.testExtractionA  s   $"LL#	
""1%..v6	
""1%../?@	
""1%../CD	
""1%../QR..0yy{ 	TZZ]224::;Q? ))+FNN;BQ?]]_
Aa    ((*HSHaHabHa1$q'188QZZ%=%=>Hab@	A 	A..066q9??L cs   +3J c                Z   ddl m} ddl m} |j                  d      }|j                  d   j                         j                  d   j                  d       |j                  d   j                         j                  d   j                  d	       |j                  d   j                         j                  d   j                  d
       |j                  d   j                         j                  d   j                  d       |j                  j                         }|j                  dd      }||_        |j                         }| j                  t        |j                        d       |j                  d   j                         j                  }| j                  t        |      d       y )Nr   rG  rI  rK  rN  z::/o:6/v:1/tb:s/g:UrsatzrL  r   z::/o:5/v:2/tb:bz::/o:4/v:2/tb:trG   z::/o:4/v:2/tb:a
      )rV  rH  rJ  rW  r   r   r   rg   rX  rv   measuresr   r   rY  r   )r5   rH  rJ  r   r]  extractr^  r   s           r   testExtractionBzTest.testExtractionB  s@   $"LL#	
""1%../IJ	
""1%../@A	
""1%../@A	
""1%../@A..0**Q#yy{TZZ!,

1%%'--UQ'r   c                   ddl m} ddl m} |j                  dd      }|j	                         j
                  D ]  }t        |t        j                        r,|j                  j                  dk(  s7|j                  d       It        |t        j                        sdd|j                  D cg c]  }|j                   c}v s|j                  d        |j                  j!                         }||_        |j%                         }y c c}w )Nr   rG  rI  schoenberg/opus19   F#z::/p:f#/o:4rV  rH  rJ  rW  r   r   r   r   Noter   r^   rg   r   Chordr_   rX  rv   r   r   r5   rH  rJ  srcri   r$   r]  unused_posts           r   testExtractionDzTest.testExtractionD  s    $"ll.2$$A!TYY'77<<4'JJ}- Au{{+AII6IqAFFI66JJ}- % ..0iik 7s   ,D	c                   ddl m} ddl m} |j                  dd      }|j	                         j
                  D ]  }t        |t        j                        rV|j                  j                  dk(  r|j                  d       |j                  j                  dk(  sa|j                  d	       st        |t        j                        sd|j                  D cg c]  }|j                   c}v r|j                  d       d|j                  D cg c]  }|j                   c}v s|j                  d	        |j                  j!                         }||_        |j%                         }y c c}w c c}w )
Nr   rG  rI  rj  rk  rl  z::/p:f#/o:4/g:F#Cz::/p:c/o:4/g:Crm  rp  s           r   testExtractionD2zTest.testExtractionD2  s   $"ll.2$$A!TYY'77<<4'JJ1277<<3&JJ/0Au{{+AII6IqAFFI66JJ1219959a166955JJ/0 % ..0iik 75s   E*E/c                    ddl m} ddl m} |j                  d      }|j                  j                         }||_        |j                         }y )Nr   rG  rI  zcorelli/opus3no1/1grave)rV  rH  rJ  rW  rX  rv   r   r   )r5   rH  rJ  rq  r]  rr  s         r   testExtractionEzTest.testExtractionE  s?    $"ll45 ..0iikr   c                   ddl m} ddl m} |j                  d      }ddddgd	d
dddgd	g}|j                  j                  ||      }|j                          |j                  D ]   }| j                  t        |d         d       " y )Nr   rG  rI  rK  zHigh Voicesz#ff0088sopranoalto)r^   r   r   z
Low Voicesz#8800fftenorbass)r   r   r   )
rV  rH  rJ  rW  rX  r   r8  r   rY  r   )r5   rH  rJ  r   r   prrj   s          r   testPartReductionAzTest.testPartReductionA  s    $"LL# &"#V, %"!6*

 --aJ-G


>>CSW.2 "r   c                X   t        |      D ]  \  }}||   }| j                  |d   |d          t        |d         D ]i  \  }}|d   |   }| j                  |d   |d          | j                  |d   |d          | j                  |d   |d   d| d| d|d    d|d           k  y	)
z`
        Utility function to compare known data but not compare floating point weights.
        r   rG   r   zfor partId z, entry z: should be z	 <-> was )r?   N)r   rY  assertAlmostEqual)	r5   r   r  partIdbrS   r   	dataMatch
dataTargets	            r   _matchWeightedDatazTest._matchWeightedData7  s     #6*IFAfAQqT1Q4( )!A$9qT!W
&&y|Z]C&&y|Z]C&&aLqM&vhhqc :&&/l^9Z]OM '  !0 +r   c                    ddl m} ddl m} ddl m} g d}g d}t	        j
                         }d}||fD ]  }	t	        j                         }
||
_        d}|	D ]Q  \  }}|
j                  |t        j                  |             |
j                  ||j                  |             ||z  }S |j                  d|
       |dz  } |du r|j                          |j                  j                  |d	
      }|j                          |j!                         }dg dg dg dg dg dgfdg dg dg dg dg dgfg}| j#                  ||       |du r.|j$                  j'                  |d      }
|
j)                          yy)1
        Artificially create test cases.
        r   rG  dynamics)graph))rG   mf)rL  f)r   r$   )rN  ff)r   r  r   rG   TFr   )r   rQ  AA?r   )rQ  rS  g?r   )rT  rR  皙?r   )      @rT  g__?r         $@rR  r  r   Dynamics)titleN)rV  rH  r  r  r   r   Partr   r   r   rn  r=  showrX  r   r8  r<  r  plotDolanrun)r5   r  rH  r  r  durDynPairsAdurDynPairsBr   pCountpairsr$   posqldynr~  r   r  s                    r   testPartReductionBzTest.testPartReductionBL  sv    	%$!LLLLN"L1EAADC Cdiib9:h..s34r	 !
 HHQNaKF 2 4<FFH--a5-A


446AA2AB	D E
 AA2AB	D E	F 	v.4<

  * 5AEEG r   c                   ddl m} ddl m} t        j                         }t        j
                         }d|_        t        j
                         }d|_        dD ]L  }|j                  t        j                  |             |j                  t        j                  |             N dD ]&  \  }}|j                  ||j                  |             ( dD ]&  \  }}|j                  ||j                  |             ( |j                  d|       |j                  d|       |j                  j                  |d	
      }	|	j                          |	j                         }
dg dg dg dgfdg dg dg dgfg}| j!                  |
|       y)r  r   rG  r  rG   )rG   r   rG   rN  r  r   r$   )r   fff)rk  ppp)r  )rG   r  )r   r  Fr  r   rR  r  r   )rR  rT  QuPu?r   r  rR  A_?r   )r   rQ  r  r   )rQ  rQ  r  r   )rR  r  r  r   N)rV  rH  r  r   r   r  r   r<   r   rn  r   r=  rX  r   r8  r<  r  r5   rH  r  r   p1p2r  r  r  r~  r   r  s               r   testPartReductionCzTest.testPartReductionC|  sS    	%$LLN[[][[]BIIdiib12IIdiib12  ;HCIIc8++C01 ;:HCIIc8++C01 ;	B	B--a5-A


4462@=? @ 2@=? @A 	v.r   c                   ddl m} ddl m} t        j                         }t        j
                         }d|_        t        j
                         }d|_        dD ]  }|rK|j                  t        j                  |             |j                  t        j                  |             P|j                  t        j                  d             |j                  t        j                  d              dD ]&  \  }}|j                  ||j                  |             ( d	D ]&  \  }}|j                  ||j                  |             ( |j                  d|       |j                  d|       |j                  j                  |      }	|	j                          |	j!                         }
dg d
g dg dgfdg dg dg dgfg}| j#                  |
|       y)zC
        Artificially create test cases. Here, uses rests.
        r   rG  r  rG   )Nr   Fr   Fr   r  r   r  )r   r  )r   r  )rk  r  rR  rR  rQ  r   )r  rR  UUUUUU?r   )r  rR  r  r   )rR  rR  g98?r   )r  rR  88?r   )r  rR  r  r   N)rV  rH  r  r   r   r  r   r<   r   rn  r   r   r=  rX  r   r8  r<  r  r  s               r   testPartReductionDzTest.testPartReductionD  s}    	%$LLN[[][[]/B		$))"56		$))"56		$))!45		$))!45 0 ;HCIIc8++C01 ;8HCIIc8++C01 9	B	B --a0


4461346 7 3@AC DE 	v.r   c                   ddl m} ddl m} t        j                         }t        j
                         }d|_        t        j
                         }d|_        dD ]  }|rK|j                  t        j                  |             |j                  t        j                  |             P|j                  t        j                  d             |j                  t        j                  d              dD ]&  \  }}|j                  ||j                  |             ( d	D ]&  \  }}|j                  ||j                  |             ( |j                  d
       |j                  d
       |j                  d|       |j                  d|       |j                  j                  |d
dd      }	|	j!                          |	j#                         }
dg dg dg dgfdg dg dg dgfg}| j%                  ||
       |j                  j                  |dd
d      }	|	j!                          |	j#                         }
dg dg dg dg dgfdg dg dg dg dgfg}| j%                  ||
       |j                  j                  |dd      }	|	j!                          |	j#                         }
dg dg dg dgfdg dg dg d gfg}| j%                  ||
       |j                  j                  |d
d
      }	|	j!                          |	j#                         }
dg d!g d"g d#g d$gfdg d%g d&g d'g d(gfg}| j%                  ||
       y))*r  r   rG  r  rG   )r   r   Fr   Fr   r  r   r  r  Tr   F)r   r   r   )r   rT  gf1۶m?r   )rT  rT  r  r   )       @rT  r  r   )rT  rT  r  r   )r  rT  r  r   r  )rR  rR  r  r   r  )r  rR  r  r   )r   rR  r  r   )rR  rR  g?r   )r  rR  r  r   r  )r   r   )r   rT  rQ  r   )r  rR  Q?r   )r  rR  r  r   )r  rR  )\(?r   )r  rR  r  r   )r   rR  g8?r   r  )r  rR  ?UUUU?r   )r  rT  r  r   )r   rR  r  r   )rR  rR  g78?r   )r  rR  88?r   )r  rT  r  r   N)rV  rH  r  r   r   r  r   r<   r   rn  r   r   r=  makeMeasuresrX  r   r8  r<  r  )r5   rH  r  r   r  r  r  r  r  r~  r  r   s               r   testPartReductionEzTest.testPartReductionE  s>    	%$LLN[[][[],B		$))"56		$))"56		$))!45		$))!45 - ;HCIIc8++C01 ;8HCIIc8++C01 9
%
%	B	B--at$)U . <


557;<<> ? ;@@B CD 	v.--au$(E . ;


5571?<=? @ @0@AC D	E 	v. --au$) . +


5570124 5 0124 56 	v. --at$( . *


557<0;;= > ??>>@ A	B 	v.r   c                    ddl m} |j                  dd      }t        |ddd      }|j	                          |j                         }y )Nr   rI  rj  r   FT)r   r   r   )rV  rJ  rW  r   r8  r<  )r5   rJ  scr~  unused_targets        r   xtestPartReductionSchoenbergz!Test.xtestPartReductionSchoenberg"  sE    "\\-q1 !	
 	

<<>r   Nr>  )r   r   r   rE  rb  rh  rs  rv  rx  r  r  r  r  r  r  r  r   r   r   r@  r@  {  sK    %$MN(x"."."30*-`!/H%/TS/p
?r   r@  c                      e Zd ZdZd Zy)TestExternalTc                P    t               }|j                  | j                         y )N)r  )r@  r  r  )r5   rM  s     r   r  zTestExternal.testPartReductionB2  s    vTYY/r   N)r   r   r   r  r  r   r   r   r  r  /  s    D0r   r  r   
_DOC_ORDER__main__)&rr   
__future__r   rH   r   typingr  unittestrV  r   r   r   music21.common.typesr   r   r	   r
   r   r   r   r   EnvironmentenvironLocalMusic21Exceptionr   ProtoM21Objectr   rt   rv   r   r   TestCaser@  r  r  __annotations__r   mainTestr   r   r   <module>r     s	   #  	       )       &{&&';<	l;; 	MG** Mb	l;; 	f' f'V	\:: 	B BJq?8 q?h08$$ 0 
H  zGT r   