
    rh                    J   % S r SSKJr  SSKrSSK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  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  SSKJr  \R*                  " S5      r " S S\	R.                  5      r " S S\R2                  5      r " S S\	R.                  5      r " S S5      r " S S\	R.                  5      r " S S5      r " S S\R>                  5      r  " S S\R>                  5      r!/ r"S \#S!'   \$S":X  a  SSKr\RJ                  " \ 5        gg)#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                      \ rS rSrSrg)ReductiveEventException*    N__name__
__module____qualname____firstlineno____static_attributes__r       T/home/james-whalen/.local/lib/python3.13/site-packages/music21/analysis/reduction.pyr   r   *       r   r   c            	      t    \ rS rSrSrSrSrSSSSS	S
SSS.rSSSSSSS.rS r	S r
S rSS jrSS jrS rSrg)ReductiveNote3   aZ  
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                    Xl         S U l        0 U l        SU l        U R	                  U R                   5        X l        X0l        X@l        g )NF)_specification_note_parameters	_isParsed_parseSpecificationmeasureIndexmeasureOffset)selfspecification	inputNoter7   r8   s        r   __init__ReductiveNote.__init__Y   sC    +
  !4!45
(*r   c                   / nU R                    Hy  nU R                   U   nX0R                  ;   d  M#  U R                  U   (       d  M9  UR                  U5        UR                  S5        UR                  U R                  U   5        M{     U R                  b5  UR                  S5        UR                  [	        U R                  5      5        SR                  U5      $ )Nr   z of  )_parameterKeysr4   appendr3   reprjoin)r9   msgkeyattrs       r   _reprInternalReductiveNote._reprInternale   s    &&C&&s+D'''##D))JJsOJJsOJJt//56 ' ::!JJvJJtDJJ'(wws|r   c                     U R                   U   $ N)r4   )r9   rE   s     r   __getitem__ReductiveNote.__getitem__s   s    $$r   c                >   [         R                  " U R                  5      U l        UR	                  5       nUR                  U R                  U R                  -   5      (       d  g UR                  U R                  5      nUSS   H  nU R                  U;  a  M  UR                  U R                  5      u  pEUR	                  5       nUR	                  5       nUR                  5       U R                  ;   d  Mr  U R                  U   nXPR                  U'   M     SU l        g )N   T)copydeepcopy_defaultParametersr4   strip
startswith_delimitValuesplit_delimitArglowerr@   r5   )r9   specargsacandidateKeyvaluerF   s          r   r6   !ReductiveNote._parseSpecificationv   s    ==)@)@Azz|t11D4F4FFGGzz$**+abA!!*"#''$*<*<"=L'--/LKKME!!#t':'::**<8).  &  r   c                    U R                   $ rJ   )r5   r9   s    r   isParsedReductiveNote.isParsed   s    ~~r   c                D   SnU R                   R                  (       a  SU R                  ;   a  [        R                  " U R                  S   5      nU R                    H[  nUR
                  R                  5       UR                  R
                  R                  5       :X  d  ME  [        R                  " U5      nM]     ON[        R                  " U R                   R                  S   5      nO [        R                  " U R                   5      nUc,  U R                  S   n[        SU< SU R                   < 35      e/ Ul        SUl        / Ul        / Ul        SUR                  l        UR                  R"                  b  SUR                  R"                  l        SnSU R                  ;   a2  U R                  S   (       a  U R                  S   UR                  l        SU R                  ;   a  U R                  S   Ul        S	U R                  ;   a-  U R                  S	   nU(       a  US
:X  a  SnOUS:X  a  SnXal        SU R                  ;   a  UR-                  U R                  S   5        SU R                  ;   a#  [        R.                  " U R                  S   5      nX4$ )z\
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&   )r3   isChordr4   r   PitchnamerW   rO   rP   pitchesr   lyricstier	   articulationsdurationdots
accidentaldisplayStatusr!   r#   r"   addLyricTextExpression)r9   nr(   subpitchParametertenhfs          r   getNoteAndTextExpression&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   )r5   r3   r4   r2   r7   r8   )rX   str)returnbool)r   r   r   r   __doc__rT   rV   r@   rQ   r<   rG   rK   r6   r`   rw   r   r   r   r   r   r   3   sn     MK 	N !
+%(3r   r   c                      \ rS rSrSrg)ScoreReductionException   r   Nr   r   r   r   r~   r~      r   r   r~   c                  |    \ rS rSrSrS rS rS r\" \\SS9r	S r
S	 r\" \\
S
S9rSS jrSS jrS rS rS rSrg)ScoreReduction   z
An object to reduce a score.
c                J    0 U l         / U l        / U l        S U l        S U l        g rJ   )_reductiveNotes_reductiveVoices_reductiveGroups_score_chordReduction)r9   keywordss     r   r<   ScoreReduction.__init__   s+    ! " " #r   c                h   [        U[        R                  5      (       d  [        S5      eUR                  (       a  [
        R                  " U5      U l        OA[        R                  " 5       nUR                  S[
        R                  " U5      5        X l        U R                  R                  SSS9  g )Ncannot set a non Streamr   r   T)recurse)
isinstancer   Streamr~   hasPartLikeStreamsrO   rP   r   ScoreinsertsetDerivationMethodr9   r\   ss      r   	_setScoreScoreReduction._setScore   sw    %//)*CDD##--.DKAHHQe,-K''(8$'Gr   c                    U R                   $ rJ   )r   r_   s    r   	_getScore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                <   [        U[        R                  5      (       d  [        S5      eUR	                  5       (       a  [
        R                  " U5      U l        g [        R                  " 5       nUR                  S[
        R                  " U5      5        X l        g )Nr   r   )
r   r   r   r~   r   rO   rP   r   r   r   r   s      r   _setChordReduction!ScoreReduction._setChordReduction   sg    %//)*CDD##%%#'==#7D AHHQe,-#$ r   c                    U R                   $ rJ   )r   r_   s    r   _getChordReduction!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                   Uc  gUR                    Hm  n[        UR                  [        R                  5      5       H>  u  pEUR                  5       R                   H  nUUUS.nU R                  XgU5        M     M@     Mo     g)zU
Remove and store all reductive events
Store in a dictionary where obj id is obj key
Npartmeasurer7   )parts	enumerategetElementsByClassr   Measurer   notes_extractNoteReductiveEvent)r9   scoreremoveAfterParsingr(   imrr   infoDicts           r   _extractReductionEvents&ScoreReduction._extractReductionEvents  st    
 =A!!"6"6v~~"FG**A()+,01 3H 33AAST	 + H r   Nc                V   Uc  S S SS.nUS   nUR                   (       d  g / nX;   a  UR                  U5      nO-SnUR                   H  nX;   d  M
  UR                  U5      nM     [        UR                   5       Hv  u  p[	        U	R
                  XS   U5      n
U
R                  5       (       d  M6  [        [        U5      5      U	R
                  -   nXR                  U'   UR                  U5        Mx     U(       a-  U H&  n[        R                  " S5      UR                   U'   M(     g g )Nr   r   r           r7   r?   )ri   getOffsetBySitevoicesr   r   textr`   ry   idr   rA   r   Lyric)r9   rr   r   r   r   removalIndicesoffsetr-   klrnrE   qs                r   r   )ScoreReduction._extractNoteReductiveEvent  s    $#'()H Yxx6&&q)FFXX6..q1F  ahh'DAqvvq>*BFKB{{}} "Q%j166),.$$S)%%a( ( #"jjn $ r   c                   0 U l         U R                  U R                  5        U R                  U R                  5        U R                   R	                  5        H  u  pUS   U R
                  ;  a  U R
                  R                  US   5        US   U R                  ;  a  U R                  R                  US   5        [        U R
                  5      S:X  a+  S U R
                  ;   a  U R
                  R                  S 5        [        U R                  5      S:X  d  M  S U R                  ;   d  M  U R                  R                  S 5        M     g )Nr$   r%      )
r   r   r   r   itemsr   rA   r   lenremove)r9   
unused_keyr   s      r   _parseReductiveNotes#ScoreReduction._parseReductiveNotes:  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                d   U R                  5         [        R                  " 5       nSn[        U R                  5      S:X  a  SnSn[        U R
                  5      S:X  a  SnU R                  (       a2  U R                  R                  R                  5       R                  SS9nO1U R                  R                  R                  5       R                  SS9nU R                   GH  n[        R                  " U5      nXVl        [        R                  " 5       nXWl        UR#                  SU5        UR%                  [        R&                  5      nU R(                  R+                  5        GHk  u  pU(       d  U
S   U:X  d  M  XR,                     nUR.                  (       dQ  UR1                  S5        U R
                   H0  n[        R2                  " 5       nXl        UR#                  SU5        M2     U(       ab  U
R5                  5       u  pUR.                  S   R7                  U
R8                  U5        U(       a  UR#                  U
R8                  U5        M  M  UR;                  U
S   5      nUc  UR.                  S   nU
R5                  5       u  pUR7                  U
R8                  U5        U(       d  GMO  UR#                  U
R8                  U5        GMn     [=        UR%                  [        R&                  5      5       H  u  nnUR.                   H4  nUR?                  5       R@                  (       d  M$  URC                  SSS	9  M6     URE                  SS
9  U[F        RH                      H  nSURJ                  l&        M     M     UR#                  SU5        GM     U R                  (       a/  U R                  R                   H  nUR#                  SU5        M     / nU R                  (       a@  U R                  R                   H&  nUR#                  SU5        URO                  U5        M(     U$ )NFrN   T)retainVoicesr   r$   Restr%   )fillGapsinPlacer   )(r   r   r   r   r   r   r   r   firsttemplater   rO   rP   r   r
   
InstrumentpartNamer   r   r   r   r   r7   r   removeByClassVoicerw   insertIntoNoteOrChordr8   getElementByIdr   r   r   	makeRestsflattenUnnecessaryVoicesr   r   stylehideObjectOnPrintrA   )r9   r   oneGrouponeVoice	mTemplategNamer,   inst	gMeasuresr   r   gMeasurevIdr-   rr   ru   r   r   rr(   srcPartss                        r   _createReductionScoreReduction._createReductionP  sE   !!#LLNt$$%*Ht$$%*H;;))//1:::NI,,2288:CCQVCWI **E i(AD((*D!MHHQ,,V^^<I
 #'"6"6"<"<">
r'{e3  )9H#?? ..v6#'#8#8C &A#&D$OOAq1 $9   " ; ; = *@@,,a1 $OOB,<,<bA  %33BwK@9 ( 2A " ; ; =//0@0@!D2$OOB,<,<bA5 #?: "!"6"6v~~"FG1Ayy{(((T4@ " **4*8499A04AGG- & H HHQNk +p ))//A 0 ;;[[&&A" ' r   c                l    U R                   c  U R                  c  [        S5      eU R                  5       $ )z.
Given a score, populate this Score reduction
zno score defined to reduce)r   chordReductionr~   r   r_   s    r   reduceScoreReduction.reduce  s4    
 ::$"5"5"=)*FGG$$&&r   )r   r   r   r   r   )T)NT)r   r   r   r   r|   r<   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r      sk    $
H Y	 0 E	%$ 02D K NU "-J3,Tl'r   r   c                      \ rS rSrSrg)PartReductionExceptioni  r   Nr   r   r   r   r   r     r   r   r   c                      \ rS rSrSr SSSSSSS.         SS jjjrS rS	 r   SS
 jrS r	SS jr
S rS rSrg)PartReductioni  a^  
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               :   Uc  g [        U[        R                  5      (       d  [        S5      eXl        / U l        0 U l        X l        X0l        X@l	        X`l
        XPl        U R                  R                   H!  nUR                  5       (       a  M  SU l          g    g )Nzprovided Stream must be ScoreF)r   r   r   r   r   _partBundles_eventSpans_partGroups_fillByMeasure_segmentByTarget_normalizeByPart_normalizeToggler   hasMeasures)	r9   srcScorer   r   r   r   r   r   r(   s	            r   r<   PartReduction.__init__  s     (FLL11()HII 5779 &+ !0 / ) ""A==??&+#	 #r   c                $   / U l         U R                  (       Ga(  U R                   GH  nUS   US   US   pCn/ nU R                  R                   H  nUc  U/n[	        UR
                  5      R                  5       nU H  n[        U[        5      (       a7  UR                  UR                  5       5      S:  a  UR                  U5          M}  [        R                  " UR                  5       U5      (       d  M{  UR                  U5        M     M     U(       d  M  UUUS.n	U R                   R                  U	5        GM     OIU R                  R                   H/  nUR
                  SU/S.n	U R                   R                  U	5        M1     U R                    Hv  n
[        U
S   5      S	:X  a  U
S   S   R                  5       U
S
'   M0  [        R                  " 5       nU
S    H  nUR!                  SU5        M     UR                  5       U
S
'   Mx     g)z
Fill the _partBundles list with dictionaries,
each dictionary defining a name (part id or supplied), a color, and list
of Parts that match.
rg   colormatchNr   )pGroupIdr  r   #666666r   rN   
parts.flat)r   r   r   r   ry   r   rW   r   findrA   rer  r   flattenr   r   r   )r9   drg   pColormatchesrs   r(   pIdr   data
partBundler   s               r   _createPartBundles PartReduction._createPartBundles  s    %%()&	1W:qzg**A #'&add)//+C$&q#..$'HHQWWY$71$<JJqM!XXaggi55JJqM % +  $# 
 !!((.1 &4 [[&&$%DD9sK!!((. ' ++J:g&'1,+5g+>q+A+I+I+K
<( MMO#G,AHHQN -+,99;
<( ,r   c                L   0 U l         U R                   GH  nUS   nUS   nUS   n/ nS nS nS nU R                  (       a  / n	U H?  n
U	R                  U
R	                  [
        R                  5      R                  5       5        MA     [        [        U	S   5      5       H  nSnU	 H(  n
X   R                  5       R                  (       d  M&  Sn  O   U(       d  M<  U	S   U   nUR                  U	S   5      nXmR                  R                  -   nUXv-
  S US.nUR                  U5        M     OUS   nUR                  5       n[        U5       H  u  pUcA  Uc  M  UR                  U5      UR                  -   nUXv-
  S US.nUR                  U5        S nMI  U[        U5      S	-
  :  aP  Uc  UR                  U5      nUR                  U5      UR                  -   nUXv-
  S US.nUR                  U5        S nM  Uc  UR                  U5      nUnM     XPR                   U'   GM     g )
Nr  r  r   r   FT)eStartspanweightr  r  rN   )r   r   r   rA   r   r   r   ranger   iterr   r   barDurationquarterLengthfindConsecutiveNotesr   )r9   r  r  r
  r   
dataEventsr  eEndeLastpartMeasuresr(   r   activeedseSrcnoteSrcs                    r   _createEventSpansPartReduction._createEventSpans/  sL   ++J!*-H(Fw'EJFDE ""!A ''(<(<V^^(L(S(S(UV  s<?34A"F)499;,,,%)F!	 * " $Q*A..|A?F #]]%@%@@D$*"&-$(#)B
 %%b)- 5f ",/ 335%g.DA y!>$#(#8#8#>ATAT#TD(.&*m(,'- 
 #))"-!%c'lQ..!>%&%6%6t%<F 006H(.&*m(,'- 
 #))"-!%!>%&%6%6t%<F !A /D *4X&] ,r   c           
       ^ U4S jnUc  UnU(       d  U R                    Hs  nUS   nU R                  US       HU  nUS   nXS   -   n	UR                  UU	SSSS	9R                  T5      R	                  5       n
U
(       d  SnOU" U
5      nXS
'   MW     Mu     gU R                    GH  n/ nUS   nU R                  US       GH  nUS   nXS   -   n	UR                  XSSSS	9R                  T5      R	                  5       n
U
R                  TSS9  [        R                  " U5      nU
(       d  UR                  U5        M  [        U
5       GH  u  pUR                  U5      nUR                  R                  nUU-   U	:  a  U	U-
  nUS::  a  U	U-
  nUS:X  a,  US   U:X  a#  UUS'   U" U5      US
'   UR                  U5        Mx  [        S:X  a`  US   U:w  aW  UU-
  US'   UR                  U5        [        R                  " U5      nUUS'   UUS'   U" U5      US
'   UR                  U5        M  [        R                  " U5      nUUS'   UUS'   U" U5      US
'   UR                  U5        GM!     GM     XR                  US   '   GM     g)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                   > [        U S5      (       a  U R                  (       a  O[        R                  " U 5      (       d  U /n SnU  H  nXR                  -  nM     U[        T5      -  $ )NisStreamr   )hasattrr'  r   
isIterablevolumeScalarr   )targets	summationr  targets      r   _dynamicToWeight8PartReduction._getValueForSpan.<locals>._dynamicToWeight  s]    w
++0@0@&&w//")I^^+	 s6{**r   Nr  r  r  r  FT)includeEndBoundarymustFinishInSpanmustBeginInSpanr  r   gMbP?r   )r   r   getElementsByOffsetr   r   extendDurationrO   rP   rA   r   r   rl   r  t)r9   r-  
splitSpanstargetToWeightr.  r  flatRefr   offsetStart	offsetEndr  wfinalBundledsFirstr   tartargetStart
targetSpandsNexts    `                 r   _getValueForSpanPartReduction._getValueForSpan  s   "		+ !-N"//
$\2**:j+ABB"$X,K +j 8I#77#!+0).(, 8  )(0  ! *51#$xL! C 0( #//
 $\2**:j+ABB"$X,K +j 8I $77+/%(, 8 ..@.@.H 
 (((>"mmB/G #**73 "+E"2&)&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                
   SnU R                    Hq  nSn[        U R                  US      5       HM  u  pEUS:X  a  US   c  XS'   M  US   nM  US   (       a  US   nM/  U(       a  X5S'   M<  US   b  MD  Ub  MI  XS'   MO     Ms     g)zr
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   )r9   minValuer  
lastWeightr   r   s         r   _extendSpansPartReduction._extendSpans  s     ++JJ"4#3#3Jz4J#KL6(|+'/8 &(\
(|%'\
#'18H-*2D'/8 M ,r   c                   0 nU R                    H5  nSnU R                  US       H  nUS   U:  d  M  US   nM     XBUS   '   M7      [        UR                  5       5      nU R                    HE  nU R                  US       H,  nU(       a  X#S      nOUnUS:w  a  US   U-  US'   M'  SUS'   M.     MG     g! [         a    Sn Ndf = f)z6
Normalize, either within each Part, or for all parts
r   r  r  rN   N)r   r   maxvalues
ValueError)r9   byPart
partMaxRefr  partMaxr   maxOfMaxbestMaxs           r   
_normalizePartReduction._normalize>  s     
++JG&&z*'=>h<') lG ? 29z*-. ,	:,,./H ++J&&z*'=>(J)?@G&Ga<$&xL7$:BxL#$BxL ? ,  	H	s   	B8 8CCc                    U R                  5         U R                  5         U R                  U R                  S9  U R	                  5         U R
                  (       a  U R                  U R                  S9  gg)z
Core processing routines.
)r6  )rM  N)r  r#  rB  r   rG  r   rR  r   r_   s    r   processPartReduction.process[  sa     	! )>)>?  OO4#8#8O9 !r   c           	         / nU R                    HW  n/ nUS   nU R                  U    H$  nUR                  US   US   US   US   /5        M&     UR                  US   U45        MY     U$ )z6
Get all data organized into bar span specifications.
r  r  r  r  r  )r   r   rA   )r9   r  r  dataList
groupSpansr   s         r   !getGraphHorizontalBarWeightedData/PartReduction.getGraphHorizontalBarWeightedDatah  s     ++JH#J/J&&z2Hr&z2h<G UV 3 KKJ/:; , r   )r   r   r   r   r   r   r   r   rJ   )
r   zlist[dict[str, t.Any]] | Noner   r{   r   r{   r   r{   r   r{   )DynamicTNF)r   r   r   r   r|   r<   r  r#  rB  rG  rR  rU  rZ  r   r   r   r   r   r     s    : % <@'+)-#').% 9% !%	%
 #'% !% #'%N17hr4n 	tGl0H%:	:r   r   c                  f    \ rS rSrS rS rS rS rS rS r	S r
S	 rSS
 jrS rS rS rS rSrg)Testi}  c                2    SSK Jn  U" U [        5       5        g )Nr   )testCopyAll)music21.test.commonTestra  globals)r9   ra  s     r   testCopyAndDeepcopyTest.testCopyAndDeepcopy~  s    7D')$r   c                   SSK Jn  SSK Jn  UR                  S5      nUR                  S   R                  5       R                  S   R                  S5        UR                  S   R                  5       R                  S   R                  S5        UR                  S   R                  5       R                  S	   R                  S
5        UR                  S   R                  5       R                  S   R                  S5        UR                  R                  5       nX4l
        UR                  5       nU R                  [        UR                  S   R                  5       R                  5      S5        UR                  R                  5       [        R                      S S n[        R"                  " 5       nU H  nUR%                  U5        M     UR                  5       n	U	R&                   V
s/ s H/  n
[)        U
5      U
R*                  U
R,                  R.                  4PM1     nn
S U l        U R                  U/ SQ5        U R                  UR                  S   R                  5       R                  S   R2                  S5        g s  sn
f )Nr   analysiscorpusbwv66.6   test   z::/o:6/tb:herer   z::/o:5/tb:fromBassrN      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   rp   	reductionr   r   r   assertEqualr   r   r   r   r   rA   notesAndRestsrB   r   rl   r  maxDifflyric)r9   rh  rj  r   srpostthree_measures
new_streamr   flat_streamr  r  s               r   testExtractionA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   -6Jc                X   SSK Jn  SSK Jn  UR                  S5      nUR                  S   R                  5       R                  S   R                  S5        UR                  S   R                  5       R                  S   R                  S	5        UR                  S   R                  5       R                  S   R                  S
5        UR                  S   R                  5       R                  S   R                  S5        UR                  R                  5       nUR                  SS5      nXTl        UR                  5       nU R                  [        UR                  5      S5        UR                  S   R                  5       R                  nU R                  [        U5      S5        g )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:trN   z::/o:4/v:2/tb:a
      )rv  rh  rj  rw  r   r  r   rp   rx  r   measuresr   r   ry  r   )r9   rh  rj  r   r}  extractr~  r  s           r   testExtractionBTest.testExtractionB  s>   $"LL#	
""1%../IJ	
""1%../@A	
""1%../@A	
""1%../@A..0**Q#yy{TZZ!,

1%%'--UQ'r   c                D   SSK Jn  SSK Jn  UR                  SS5      nUR	                  5       R
                   H  n[        U[        R                  5      (       a/  UR                  R                  S:X  a  UR                  S5        MO  MQ  [        U[        R                  5      (       d  Mr  SUR                   Vs/ s H  oUR                  PM     sn;   d  M  UR                  S5        M     UR                  R!                  5       nX6l        UR%                  5       ng s  snf )Nr   rg  ri  schoenberg/opus19   F#z::/p:f#/o:4rv  rh  rj  rw  r  r   r   r   Noter   rg   rp   r   Chordrh   rx  r   r   r   r9   rh  rj  srcrr   r(   r}  unused_posts           r   testExtractionDTest.testExtractionD  s    $"ll.2$$A!TYY''77<<4'JJ}- ( Au{{++AII6IqFFI66JJ}- % ..0iik 7s   :Dc                    SSK Jn  SSK Jn  UR                  SS5      nUR	                  5       R
                   GH  n[        U[        R                  5      (       aZ  UR                  R                  S:X  a  UR                  S5        UR                  R                  S:X  a  UR                  S	5        M{  M}  [        U[        R                  5      (       d  M  SUR                   Vs/ s H  oUR                  PM     sn;   a  UR                  S5        SUR                   Vs/ s H  oUR                  PM     sn;   d  GM  UR                  S	5        GM     UR                  R!                  5       nX6l        UR%                  5       ng s  snf s  snf )
Nr   rg  ri  r  r  r  z::/p:f#/o:4/g:F#Cz::/p:c/o:4/g:Cr  r  s           r   testExtractionD2Test.testExtractionD2  s   $"ll.2$$A!TYY''77<<4'JJ1277<<3&JJ/0 'Au{{++AII6IqFFI66JJ1219959a66955JJ/0 % ..0iik 75s   &F!Fc                    SSK Jn  SSK Jn  UR                  S5      nUR                  R                  5       nX4l        UR                  5       ng )Nr   rg  ri  zcorelli/opus3no1/1grave)rv  rh  rj  rw  rx  r   r   r   )r9   rh  rj  r  r}  r  s         r   testExtractionETest.testExtractionE  s=    $"ll45 ..0iikr   c                   SSK Jn  SSK Jn  UR                  S5      nSSSS/S	.S
SSS/S	./nUR                  R                  X4S9nUR                  5         UR                   H!  nU R                  [        US   5      S5        M#     g )Nr   rg  ri  rk  zHigh Voicesz#ff0088sopranoalto)rg   r  r  z
Low Voicesz#8800fftenorbass)r   r  r   )
rv  rh  rj  rw  rx  r   rU  r   ry  r   )r9   rh  rj  r   r   prrs   s          r   testPartReductionATest.testPartReductionA!  s    $"LL# &"#V, %"!6*

 --a-G


>>CSW.2 "r   c                \   [        U5       H  u  p4X   nU R                  US   US   5        [        US   5       Hj  u  pgUS   U   nU R                  US   US   5        U R                  US   US   5        U R                  US   US   SU SU S3SUS    SUS    3-   S	9  Ml     M     g
)zP
Utility function to compare known data but not compare floating point weights.
r   rN   r   zfor partId z, entry z: z
should be z	 <-> was )rD   N)r   ry  assertAlmostEqual)	r9   r  r-  partIdbrZ   r   	dataMatch
dataTargets	            r   _matchWeightedDataTest._matchWeightedData9  s     #6*IFAQqT1Q4( )!A$qT!W
&&y|Z]C&&y|Z]C&&aLqM&vhhqc<'	!~Yz!}oNO '  !0 +r   c           	        SSK Jn  SSK Jn  SSK Jn  / SQn/ SQn[        R
                  " 5       nSnXV4 H  n	[        R                  " 5       n
Xl        SnU	 HM  u  pU
R                  U[        R                  " US95        U
R                  XR                  U5      5        X-  nMO     UR                  SU
5        US-  nM     USL a  UR                  5         UR                  R                  US	S
9nUR                  5         UR!                  5       nS/ SQ/ SQ/ SQ/ SQ/ SQ/4S/ SQ/ SQ/ SQ/ SQ/ SQ/4/nU R#                  UU5        USL a+  UR$                  R'                  USS9n
U
R)                  5         gg)!
Artificially create test cases.
r   rg  dynamics)graph))rN   mf)rl  f)r   r(   )rn  ff)r   r  r  rN   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   r  r\  showrx  r   rU  rZ  r  plotDolanrun)r9   r  rh  r  r  durDynPairsAdurDynPairsBr   pCountpairsr(   posqldynr  r  r-  s                    r   testPartReductionBTest.testPartReductionBN  sl    	%$!LLLLN"1EADC diib9:..s34	 !
 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                   SSK Jn  SSK Jn  [        R                  " 5       n[        R
                  " 5       nSUl        [        R
                  " 5       nSUl        S HI  nUR                  [        R                  " US95        UR                  [        R                  " US95        MK     S H%  u  pxUR                  XrR                  U5      5        M'     S H%  u  pxUR                  XrR                  U5      5        M'     UR                  SU5        UR                  SU5        UR                  R                  US	S
9n	U	R                  5         U	R                  5       n
S/ SQ/ SQ/ SQ/4S/ SQ/ SQ/ SQ/4/nU R!                  X5        g)r  r   rg  r  rN   )rN   r   rN   rn  r  r   r(   )r   fff)r  ppp)r  )rN   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   rA   r   r  r   r\  rx  r   rU  rZ  r  r9   rh  r  r   p1p2r  r  r  r  r  r-  s               r   testPartReductionCTest.testPartReductionC~  sI    	%$LLN[[][[]BIIdiib12IIdiib12  ;HCIIc++C01 ;:HCIIc++C01 ;	B	B--a5-A


4462@=? @ 2@=? @A 	.r   c                   SSK Jn  SSK Jn  [        R                  " 5       n[        R
                  " 5       nSUl        [        R
                  " 5       nSUl        S H  nU(       aH  UR                  [        R                  " US95        UR                  [        R                  " US95        MR  UR                  [        R                  " SS95        UR                  [        R                  " SS95        M     S H%  u  pxUR                  XrR                  U5      5        M'     S	 H%  u  pxUR                  XrR                  U5      5        M'     UR                  SU5        UR                  SU5        UR                  R                  U5      n	U	R                  5         U	R!                  5       n
S/ S
Q/ SQ/ SQ/4S/ SQ/ SQ/ SQ/4/nU R#                  X5        g)z3
Artificially create test cases. Here, uses rests.
r   rg  r  rN   )Nr   Fr   Fr   r  r   r  )r   r  )r   r  )r  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   rA   r   r  r   r   r\  rx  r   rU  rZ  r  r  s               r   testPartReductionDTest.testPartReductionD  ss    	%$LLN[[][[]/B		$))"56		$))"56		$))!45		$))!45 0 ;HCIIc++C01 ;8HCIIc++C01 9	B	B --a0


4461346 7 3@AC DE 	.r   c                n   SSK Jn  SSK Jn  [        R                  " 5       n[        R
                  " 5       nSUl        [        R
                  " 5       nSUl        S H  nU(       aH  UR                  [        R                  " US95        UR                  [        R                  " US95        MR  UR                  [        R                  " SS95        UR                  [        R                  " SS95        M     S H%  u  pxUR                  XrR                  U5      5        M'     S	 H%  u  pxUR                  XrR                  U5      5        M'     UR                  S
S9  UR                  S
S9  UR                  SU5        UR                  SU5        UR                  R                  US
SSS9n	U	R!                  5         U	R#                  5       n
S/ SQ/ SQ/ SQ/4S/ SQ/ SQ/ SQ/4/nU R%                  X5        UR                  R                  USS
SS9n	U	R!                  5         U	R#                  5       n
S/ SQ/ SQ/ SQ/ SQ/4S/ SQ/ SQ/ SQ/ SQ/4/nU R%                  X5        UR                  R                  USSS9n	U	R!                  5         U	R#                  5       n
S/ SQ/ SQ/ SQ/4S/ SQ/ SQ/ S Q/4/nU R%                  X5        UR                  R                  US
S
S9n	U	R!                  5         U	R#                  5       n
S/ S!Q/ S"Q/ S#Q/ S$Q/4S/ S%Q/ S&Q/ S'Q/ S(Q/4/nU R%                  X5        g))*r  r   rg  r  rN   )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   rA   r   r  r   r   r\  makeMeasuresrx  r   rU  rZ  r  )r9   rh  r  r   r  r  r  r  r  r  r-  r  s               r   testPartReductionETest.testPartReductionE  s.    	%$LLN[[][[],B		$))"56		$))"56		$))!45		$))!45 - ;HCIIc++C01 ;8HCIIc++C01 9
%
%	B	B--at$)U . <


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


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


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


557<0;;= > ??>>@ A	B 	.r   c                    SSK Jn  UR                  SS5      n[        USSSS9nUR	                  5         UR                  5       ng )Nr   ri  r  r   FT)r   r   r   )rv  rj  rw  r   rU  rZ  )r9   rj  scr  unused_targets        r   xtestPartReductionSchoenberg!Test.xtestPartReductionSchoenberg$  sE    "\\-q1 !	
 	

<<>r   )r{  Nr]  )r   r   r   r   rd  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r_  r_  }  sK    %$MN(x"."."30*-`!/H%/TS/p
?r   r_  c                      \ rS rSrSrS rSrg)TestExternali1  Tc                J    [        5       nUR                  U R                  S9  g )N)r  )r_  r  r  )r9   rm  s     r   r  TestExternal.testPartReductionB4  s    vTYY/r   r   N)r   r   r   r   r  r  r   r   r   r   r  r  1  s    D0r   r  r   
_DOC_ORDER__main__)&r|   
__future__r   rO   r  typingr5  unittestrv  r   r   r   music21.common.typesr   r   r	   r
   r   r   r   r   EnvironmentenvironLocalMusic21Exceptionr   ProtoM21Objectr   r~   r   r   r   TestCaser_  r  r  __annotations__r   mainTestr   r   r   <module>r     s   #  	       )       &&';<	l;; 	MG** Mb	l;; 	f' f'V	\:: 	C CLq?8 q?h08$$ 0 
H  zT r   