
    3j                    (   d Z ddlmZ ddlm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  ej                  d
      Z G d dej                        Z G d d      Z G d dej"                        Zedk(  rddlZ ej(                  e       yy)zY
Various tools and utilities to find correlations between disparate objects in a Stream.
    )annotations)OrderedDictN)exceptions21)note)chord)dynamics)environmentzanalysis.correlatec                      e Zd Zy)CorrelateExceptionN)__name__
__module____qualname__     G/DATA/.local/lib/python3.12/site-packages/music21/analysis/correlate.pyr   r      s    r   r   c                  &    e Zd ZdZd ZddZddZy)ActivityMatcha  
    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                j    t        |d      rd|j                  vrt        d      || _        d | _        y )NclassesStreamznon-stream provided as argument)hasattrr   r   	streamObjdata)selfr   s     r   __init__zActivityMatch.__init__2   s3    y),	@Q@Q0Q$%FGG"	r   Nc                "   | t         j                  t        j                  f}|t        j
                  }g }| j                  j                         }|j                  |      }|j                  |      D ]  }|j                  |g d        |j                  |      D ]^  }|j                  }||j                  j                  z   }|D ]2  }||d   j                  cxk  r|k  sn |d   j                  |       4 ` || _        | j                  S )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   _findActivezActivityMatch._findActive9   s     ))U[[1J!))J^^++-
..z:
 "44Z@GKK  A "44Z@G~~H 0 0 > >>FuU|22<f<%L''0	 	 A 	yyr   c                   t         j                  t        j                  f}t        j
                  }||fD ];  }| j                  j                         j                  |      }|r/t        d|        | j                  ||       d }d }g }| j                  D ][  }	|	d   }
|
j                  rt        |
      }n|
g}|D ]4  }
|	d   D ]*  } ||
      } ||      }|||j                  ||f       , 6 ] |r|S t               }|D ]  }||vrd||<   ||xx   dz  cc<    g }|D ]  }|j                  |d   |d   ||   f       ! |S )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)
        zFcannot create correlation: an object that is not found in the Stream: c                .    | j                   j                  S N)pitchpses    r   <lambda>z.ActivityMatch.pitchToDynamic.<locals>.<lambda>   s    qwwzzr   c                T    t         j                  j                  | j                        S r4   )r   
shortNamesindexvaluer7   s    r   r9   z.ActivityMatch.pitchToDynamic.<locals>.<lambda>   s    x**009r   r   r   r      )r   r   r   r    r   r!   r   recurser$   r   r1   r   isChordlistr%   r   )r   
dataPointsr)   r*   objNamedstCheckfxfypairsr0   entrySrcsubentryDstxy
dictionarycoordkeys                     r   pitchToDynamiczActivityMatch.pitchToDynamicd   s   4 ii-
%%
"J/G~~--/BB7KH( *MMTI*W X X 0 	Z0!9 YYEU|H 8nj %eH8A8AyAIaV, !-   & L !]
EJ&$%
5!u"  CLL#a&#a&*S/:; r   )NN)T)r   r   r   __doc__r   r1   rP   r   r   r   r   r   "   s    (VKr   r   c                      e Zd Zd Zd Zy)Testc                2    ddl m}  || t                      y )Nr   )testCopyAll)music21.test.commonTestrU   globals)r   rU   s     r   testCopyAndDeepcopyzTest.testCopyAndDeepcopy   s    7D')$r   c                    ddl m} |j                  dd      }t        |j	                               }|j                         }| j                  t        |      d       y )Nr   )corpuszschoenberg/opus19   o   )music21rZ   parser   r"   rP   assertEquallen)r   rZ   ab	dataPairss        r   testActivityMatchPitchToDynamicz$Test.testActivityMatchPitchToDynamic   sJ    "LL,a0!))+&$$&	 	Y-r   N)r   r   r   rX   rd   r   r   r   rS   rS      s    %	.r   rS   __main__)rQ   
__future__r   collectionsr   unittestr]   r   r   r   r   r	   EnvironmentenvironLocalMusic21Exceptionr   r   TestCaserS   r   mainTestr   r   r   <module>rn      s    # #       &{&&';<	66 	
M Mb.8 .& zGT r   