
    rh                    *   S r SSKJr  SSKJ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  \R                  " S
5      r " S S\R                  5      r " S S5      r " S S\R"                  5      r\S:X  a  SSKr\R(                  " \5        gg)zY
Various tools and utilities to find correlations between disparate objects in a Stream.
    )annotations)OrderedDictN)exceptions21)note)chord)dynamics)environmentzanalysis.correlatec                      \ rS rSrSrg)CorrelateException    N)__name__
__module____qualname____firstlineno____static_attributes__r       T/home/james-whalen/.local/lib/python3.13/site-packages/music21/analysis/correlate.pyr   r      s    r   r   c                  2    \ rS rSrSrS rSS jrS	S jrSrg)
ActivityMatch#   a  
Given a Stream, find if one object is active while another is also active.

Plotting routines to graph the output of dedicated methods in this class are available.

:class:`~music21.graph.plot.ScatterPitchSpaceDynamicSymbol` and
:class:`~music21.graph.plot.ScatterWeightedPitchSpaceDynamicSymbol`
employs the :meth:`~music21.analysis.correlate.ActivityMatch.pitchToDynamic` method.

Sample output is as follows:

.. image:: images/ScatterWeightedPitchSpaceDynamicSymbol.*
    :width: 600

c                v    [        US5      (       a  SUR                  ;  a  [        S5      eXl        S U l        g )NclassesStreamznon-stream provided as argument)hasattrr   r   	streamObjdata)selfr   s     r   __init__ActivityMatch.__init__3   s4    y),,	@Q@Q0Q$%FGG"	r   Nc                4   Uc   [         R                  [        R                  4nUc  [        R
                  n/ nU R                  R                  5       nUR                  U5      nUR                  U5       H  nUR                  U/ S.5        M     UR                  U5       Hc  nUR                  nXeR                  R                  -   nU H6  nXhS   R                  s=::  a  U::  d  M  O  M"  US   R                  U5        M8     Me     X0l        U R                  $ )z
Do the analysis, finding correlations of src with dst
returns an ordered list of dictionaries, in the form
{'src': obj, 'dst': [objs]}

)srcdstr"   r#   )r   Noter   Chordr   Dynamicr   flattenextendDurationgetElementsByClassappendoffsetdurationquarterLengthr   )	r   
objNameSrc
objNameDstpost
streamFlatelementdstStartdstEndentrys	            r   _findActiveActivityMatch._findActive:   s     ))U[[1J!))J^^++-
..z:
 "44Z@GKK  A "44Z@G~~H 0 0 > >>FU|22<f<<%L''0	 	 A 	yyr   c                   [         R                  [        R                  4n[        R
                  nX#4 HD  nU R                  R                  5       R                  U5      nU(       a  M5  [        SSU 3-   5      e   U R                  X#5        S nS n/ nU R                   Hg  n	U	S   n
U
R                  (       a  [        U
5      nOU
/nU H9  n
U	S    H-  nU" U
5      nU" U5      nUb  Uc  M  UR                  X45        M/     M;     Mi     U(       a  U$ [        5       nU H  nUU;  a  SUU'   UU==   S-  ss'   M     / nU H   nUR                  US   US   UU   45        M"     U$ )	a  
Create an analysis of pitch to dynamic symbol.

If `dataPoints` is True, all data matches between source and destination are returned.
If False, 3 point weighted coordinates are created for each unique match.

No dynamics here.

>>> s = corpus.parse('bach/bwv8.6.xml')
>>> am = analysis.correlate.ActivityMatch(s.parts.first().flatten())
>>> am.pitchToDynamic()
Traceback (most recent call last):
music21.analysis.correlate.CorrelateException: cannot create correlation:
    an object that is not found in the Stream: <class 'music21.dynamics.Dynamic'>

Many dynamics

>>> s = corpus.parse('schoenberg/opus19/movement2')
>>> am = analysis.correlate.ActivityMatch(s.parts.first().flatten())
>>> data = am.pitchToDynamic()
>>> len(data)
39
>>> data[0]
(83.0, 7)
z%cannot create correlation: an object z!that is not found in the Stream: c                .    U R                   R                  $ N)pitchpses    r   <lambda>.ActivityMatch.pitchToDynamic.<locals>.<lambda>   s    qwwzzr   c                T    [         R                  R                  U R                  5      $ r:   )r   
shortNamesindexvaluer=   s    r   r?   r@      s    x**009r   r"   r#   r      )r   r$   r   r%   r   r&   r   recurser)   r   r6   r   isChordlistr*   r   )r   
dataPointsr.   r/   objNamedstCheckfxfypairsr5   entrySrcsubentryDstxy
dictionarycoordkeys                     r   pitchToDynamicActivityMatch.pitchToDynamice   s}   4 ii-
%%
"/G~~--/BB7KH8()P-Nwi+X*Y Z Z 0 	0!9 YYEU|H 8nj %eH8A8AyAIaV, !-   & L !]
EJ&$%
5!u"  CLL#a&#a&*S/:; r   )r   r   )NN)T)	r   r   r   r   __doc__r   r6   rW   r   r   r   r   r   r   #   s    (VKr   r   c                       \ rS rSrS rS rSrg)Test   c                2    SSK Jn  U" U [        5       5        g )Nr   )testCopyAll)music21.test.commonTestr^   globals)r   r^   s     r   testCopyAndDeepcopyTest.testCopyAndDeepcopy   s    7D')$r   c                    SSK Jn  UR                  SS5      n[        UR	                  5       5      nUR                  5       nU R                  [        U5      S5        g )Nr   )corpuszschoenberg/opus19   o   )music21rd   parser   r'   rW   assertEquallen)r   rd   ab	dataPairss        r   testActivityMatchPitchToDynamic$Test.testActivityMatchPitchToDynamic   sJ    "LL,a0!))+&$$&	 	Y-r   r   N)r   r   r   r   ra   rn   r   r   r   r   r[   r[      s    %	.r   r[   __main__)rY   
__future__r   collectionsr   unittestrg   r   r   r   r   r	   EnvironmentenvironLocalMusic21Exceptionr   r   TestCaser[   r   mainTestr   r   r   <module>ry      s    # #       &&';<	66 	
M Mb.8 .& zT r   