§
    ƒØjá<  ã                  óx  — 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 e
j        e
j        e
j        e
j        e
j        dœZded	<   g d
¢Zded<   d„ eD ¦   «         Zd%d„Zd&d„Zd'd„Zd„ Zd(d„Zd)d„Zd*d„Z	 	 	 	 d+d,d!„Z G d"„ d#ej        ¦  «        Zed$k    rddlZ ej         e¦  «         dS dS )-z7
Functions that find appropriate plots for graph.plot.
é    )ÚannotationsN)Úaxis)Úplot)Ú
primitives)ÚambitusÚdolanÚinstrumentsÚkeyÚ	pianorollz%dict[str, type[plot.PlotStreamMixin]]ÚPLOTCLASS_SHORTCUTS))ÚhorizontalbarÚbarÚ
horizontalr   Úpiano)Ú	histogramÚhistoÚcount)ÚscatterÚpoint)ÚscatterweightedÚweightedscatterÚweighted)Ú3dbarsÚ3d)Ú	colorgridÚgridÚwindowÚwindowed)ÚhorizontalbarweightedÚbarweightedÚweightedbarzlist[tuple[str, ...]]ÚFORMAT_SYNONYMSc                ó   — g | ]
}|d          ‘ŒS )r   © )Ú.0Úsyns     ú‹/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/graph/findPlot.pyú
<listcomp>r(   /   s   € Ð
-Ð
-Ð
-�cˆ3ˆqŒ6Ð
-Ð
-Ð
-ó    Úreturnú list[type[plot.PlotStreamMixin]]c                 ó¤  — g } t          t          j        ¦  «        D ]³}t          t          |¦  «        }t	          |¦  «        r�t          |t          j        ¦  «        sst          |d¦  «        rct          j	        |j
        v rPt          j        |j
        v r=|                      t          j        t           t          j	                 |¦  «        ¦  «         Œ´| S )a{  
    return a list of all PlotStreamMixin subclasses. Returns a list sorted by name

    >>> graph.findPlot.getPlotClasses()
    [<class 'music21.graph.plot.Dolan'>,
     <class 'music21.graph.plot.Features'>,
     <class 'music21.graph.plot.Histogram'>,
     <class 'music21.graph.plot.HistogramPitchClass'>,
     <class 'music21.graph.plot.HistogramPitchSpace'>,
     ...]
    Ú__mro__)Úsortedr   Ú__dict__ÚgetattrÚcallableÚ
isinstanceÚtypesÚFunctionTypeÚhasattrÚPlotStreamMixinr-   r   ÚGraphÚappendÚtÚcastÚtype)ÚallPlotÚiÚnames      r'   ÚgetPlotClassesr?   2   s¹   € ð 13€GÝ•D”MÑ"Ô"ð Eð EˆÝ•t˜QÑÔˆå�T‰NŒNð 	EÝ" 4­Ô);Ñ<Ô<ð	Eå˜D )Ñ,Ô,ð	Eõ Ô(¨D¬LÐ8Ð8ÝÔ$¨¬Ð4Ð4Ø�NŠN�1œ6¥$¥tÔ';Ô"<¸dÑCÔCÑDÔDÐDøØ€Nr)   úlist[type[axis.Axis]]c                 ó  — g } t          t          j        ¦  «        D ]o}t          t          |¦  «        }t	          |¦  «        rIt          |t          j        ¦  «        s/t          |t          j	        ¦  «        r|  
                    |¦  «         Œp| S )a7  
    return a list of all Axis subclasses.  Returns a list sorted by name

    >>> graph.findPlot.getAxisClasses()
    [<class 'music21.graph.axis.Axis'>,
     <class 'music21.graph.axis.CountingAxis'>,
     <class 'music21.graph.axis.DynamicsAxis'>,
     <class 'music21.graph.axis.OffsetAxis'>,
     ...]
    )r.   r   r/   r0   r1   r2   r3   r4   Ú
issubclassÚAxisr8   )ÚallAxisr=   r>   s      r'   ÚgetAxisClassesrE   K   s‚   € ð &(€GÝ•D”MÑ"Ô"ð !ð !ˆÝ•t˜QÑÔˆÝ�T‰NŒNð 	!Ý" 4­Ô);Ñ<Ô<ð	!å˜t¥T¤YÑ/Ô/ð	!ð �NŠN˜4Ñ Ô Ð øØ€Nr)   Fc                ó®   — |€t          ¦   «         }g }|D ]?}| r|                     |j        ¦  «         Œ|                     |j        d         ¦  «         Œ@|S )a   
    >>> graph.findPlot.getAxisQuantities()
    ['generic', 'count', 'dynamic', 'offset', 'offsetEnd',
     'pitchGeneric', 'pitchClass', 'pitchSpace', 'octave', 'position', 'quarterLength']

    >>> graph.findPlot.getAxisQuantities(synonyms=True)
    ['generic', 'one', 'nothing', 'blank', 'count', 'quantity', 'frequency', ...]

    >>> theseAxes = [graph.axis.CountingAxis, graph.axis.OffsetAxis]
    >>> graph.findPlot.getAxisQuantities(axesToCheck=theseAxes)
    ['count', 'offset']

    >>> graph.findPlot.getAxisQuantities(True, axesToCheck=theseAxes)
    ['count', 'quantity', 'frequency', 'counting',
     'offset', 'measure', 'offsets', 'measures', 'time']

    Nr   )rE   ÚextendÚ
quantitiesr8   )ÚsynonymsÚaxesToCheckÚallQuantitiesÚaxClasss       r'   ÚgetAxisQuantitiesrM   `   sp   € ð$ ÐÝ$Ñ&Ô&ˆØ€MØð 8ð 8ˆØð 	8Ø× Ò  Ô!3Ñ4Ô4Ð4Ð4à× Ò  Ô!3°AÔ!6Ñ7Ô7Ð7Ð7ØÐr)   c                óŠ   — |                       ¦   «         } |                      dd¦  «        } t          D ]}| |v r
|d         c S Œ| S )aá  
    Replace possible user format strings with defined format names as used herein.
    Returns string unaltered if no match.

    >>> graph.findPlot.userFormatsToFormat('horizontal')
    'horizontalbar'
    >>> graph.findPlot.userFormatsToFormat('Weighted Scatter')
    'scatterweighted'
    >>> graph.findPlot.userFormatsToFormat('3D')
    '3dbars'

    Unknown formats pass through unaltered.

    >>> graph.findPlot.userFormatsToFormat('4D super chart')
    '4dsuperchart'
    ú Ú r   )ÚlowerÚreplacer"   )Ú
userFormatÚopts     r'   ÚuserFormatsToFormatrU   }   s^   € ð$ ×!Ò!Ñ#Ô#€JØ×#Ò# C¨Ñ,Ô,€Jåð ð ˆØ˜ÐÐØ�q”6ˆMˆMˆMð ð
 Ðr)   c                óÚ   — t          | ¦  «                             ¦   «         } |€t          ¦   «         }g }|D ]4}|j                             ¦   «         | k    r|                     |¦  «         Œ5|S )a|  
    Given a graphFormat, find a list of plots that match:

    >>> graph.findPlot.getPlotClassesFromFormat('scatterweighted')
    [<class 'music21.graph.plot.ScatterWeighted'>,
     <class 'music21.graph.plot.ScatterWeightedPitchClassQuarterLength'>,
     <class 'music21.graph.plot.ScatterWeightedPitchSpaceDynamicSymbol'>,
     <class 'music21.graph.plot.ScatterWeightedPitchSpaceQuarterLength'>]

    Or give a list of plot classes to check:

    >>> pcs = [graph.plot.ScatterWeighted, graph.plot.Dolan]
    >>> graph.findPlot.getPlotClassesFromFormat('scatterweighted', pcs)
    [<class 'music21.graph.plot.ScatterWeighted'>]

    )rU   rQ   r?   Ú	graphTyper8   )ÚgraphFormatÚcheckPlotClassesÚfilteredPlotsÚps       r'   ÚgetPlotClassesFromFormatr\   ›   sw   € õ" & kÑ2Ô2×8Ò8Ñ:Ô:€KàÐÝ)Ñ+Ô+ÐØ€MØð $ð $ˆØŒ;×ÒÑÔ +Ò-Ð-Ø× Ò  Ñ#Ô#Ð#øØÐr)   Ú	axisValueÚstrútype[axis.Axis] | Nonec                óP   — t          ¦   «         D ]}t          || ¦  «        r|c S ŒdS )a_  
    given an axis value return the single best axis for the value, or None

    uses Axis.quantities

    >>> getAxis = graph.findPlot.getAxisClassFromValue

    >>> getAxis('counting')
    <class 'music21.graph.axis.CountingAxis'>

    >>> getAxis('pc')
    <class 'music21.graph.axis.PitchClassAxis'>

    >>> print(getAxis('boogie'))
    None
    N)rE   ÚaxisMatchesValue)r]   ÚthisAxiss     r'   ÚgetAxisClassFromValuerc   ·   s>   € õ" #Ñ$Ô$ð ð ˆÝ˜H iÑ0Ô0ð 	ØˆOˆOˆOð	àˆ4r)   Ú	axisClassútype[axis.Axis] | axis.AxisÚboolc                óx   — |                      ¦   «         }| j        D ]}|                      ¦   «         |k    r dS ŒdS )a„  
    Returns Bool about whether axisValue.lower() is anywhere in axisClass.quantities

    >>> ax = graph.axis.CountingAxis
    >>> graph.findPlot.axisMatchesValue(ax, 'counting')
    True
    >>> graph.findPlot.axisMatchesValue(ax, 'count')
    True
    >>> graph.findPlot.axisMatchesValue(ax, 'offset')
    False

    Works on an instantiated object as well:

    >>> ax = graph.axis.CountingAxis()
    >>> graph.findPlot.axisMatchesValue(ax, 'counting')
    True
    >>> graph.findPlot.axisMatchesValue(ax, 'flute')
    False

    * Changed in v8: Must send a subclass of axis.Axis or an instance.
        `None` is no longer supported.
    TF)rQ   rH   )rd   r]   Úvs      r'   ra   ra   Î   sI   € ð0 —’Ñ!Ô!€IØÔ!ð ð ˆØ�7Š7‰9Œ9˜	Ò!Ð!Ø�4�4ð "àˆ5r)   rX   ú
str | Nonec                ó(  ‡‡‡‡— ˆˆˆfd„}| ‰‰‰gdgdz  k    rd} | t           v rt           |          g}nt          | ¦  «        }|s| r| ‰‰cŠŠŠd} t          ¦   «         }g Šd‰fd‰fd‰ffD ]^\  }}|D ]V}|€Œ||j        vr‰                     |¦  «         Œ$|j        |         }	t          |	|¦  «        s‰                     |¦  «         ŒWŒ_ˆfd„|D ¦   «         }
|
r"| st          |
¦  «        d	k    r|
S  ||
¦  «        S g Šd‰fd‰fd‰ffD ]Y\  }}|D ]Q}|€Œd
}|j                             ¦   «         D ]\  }}	t          |	|¦  «        rd} nŒ|s‰                     |¦  «         ŒRŒZˆfd„|D ¦   «         }
|
r"| st          |
¦  «        d	k    r|
S  ||
¦  «        S t          j	        ¦   «         }d‰fd‰fd‰ffD ]\  }}|€Œt          |¦  «        }|€Œ|||<   Œ t          |¦  «        d	k    r|d         |fgS  ||¦  «        }|r|d         |fgS |d         |fgS )a¥
  
    Returns either a list of plot classes to make if there is a predetermined class

    or a list of tuples where the first element of each tuple is the plot class
    and the second is a dict of {'x': axisXClass, 'y': axisYClass} etc.

    Default is pianoroll

    >>> graph.findPlot.getPlotsToMake()
    [<class 'music21.graph.plot.HorizontalBarPitchSpaceOffset'>]

    >>> graph.findPlot.getPlotsToMake('scatter')
    [<class 'music21.graph.plot.Scatter'>,
     <class 'music21.graph.plot.ScatterPitchClassOffset'>,
     <class 'music21.graph.plot.ScatterPitchClassQuarterLength'>,
     <class 'music21.graph.plot.ScatterPitchSpaceDynamicSymbol'>,
     <class 'music21.graph.plot.ScatterPitchSpaceQuarterLength'>]

    >>> graph.findPlot.getPlotsToMake('scatter', 'offset', 'pitchClass')
    [<class 'music21.graph.plot.ScatterPitchClassOffset'>]

    Try in wrong order:

    >>> graph.findPlot.getPlotsToMake('scatter', 'pitchClass', 'offset')
    [<class 'music21.graph.plot.ScatterPitchClassOffset'>]

    Try giving just one value:

    >>> graph.findPlot.getPlotsToMake('scatter', 'offset')
    [<class 'music21.graph.plot.ScatterPitchClassOffset'>]

    >>> graph.findPlot.getPlotsToMake('scatter', 'ql')  # abbreviation
    [<class 'music21.graph.plot.ScatterPitchClassQuarterLength'>,
     <class 'music21.graph.plot.ScatterPitchSpaceQuarterLength'>]

    Just one value, but it is in the wrong axis:

    >>> graph.findPlot.getPlotsToMake('scatter', 'pitchClass')
    [<class 'music21.graph.plot.ScatterPitchClassOffset'>,
     <class 'music21.graph.plot.ScatterPitchClassQuarterLength'>]

    Create a graph that does not exist:

    >>> graph.findPlot.getPlotsToMake('scatter', 'offset', 'dynamics')
    [(<class 'music21.graph.plot.Scatter'>,
      OrderedDict([('x', <class 'music21.graph.axis.OffsetAxis'>),
                   ('y', <class 'music21.graph.axis.DynamicsAxis'>)]))]

    Just a couple of values:

    >>> graph.findPlot.getPlotsToMake('offset', 'dynamics')
    [(<class 'music21.graph.plot.Scatter'>,
      OrderedDict([('x', <class 'music21.graph.axis.OffsetAxis'>),
                   ('y', <class 'music21.graph.axis.DynamicsAxis'>)]))]

    Just one value:

    >>> graph.findPlot.getPlotsToMake('octave')
    [(<class 'music21.graph.plot.Histogram'>,
      OrderedDict([('x', <class 'music21.graph.axis.PitchSpaceOctaveAxis'>)]))]

    Three values:

    >>> graph.findPlot.getPlotsToMake('offset', 'dynamics', 'count')
    [(<class 'music21.graph.plot.ScatterWeighted'>,
      OrderedDict([('x', <class 'music21.graph.axis.OffsetAxis'>),
                   ('y', <class 'music21.graph.axis.DynamicsAxis'>),
                   ('z', <class 'music21.graph.axis.CountingAxis'>)]))]

    c                ó    •— t          d„ ‰‰‰fD ¦   «         ¦  «        }d}|dk    rd}n|dk    rd}n|dk    rd}t          || ¦  «        }|r|S | S )	Nc                ó   — g | ]}|®d‘ŒS )Né   r$   )r%   Úvals     r'   r(   z9getPlotsToMake.<locals>._bestPlotType.<locals>.<listcomp>9  s   € ÐPÐPÐP˜SÀÀ�qÀÀÀr)   rP   é   r   é   r   rm   r   )Úlenr\   )ÚgraphClassesToChooseFromÚnumAxesÚbestGraphTypeÚinnerFilteredClassesÚxValueÚyValueÚzValues       €€€r'   Ú_bestPlotTypez%getPlotsToMake.<locals>._bestPlotType7  s~   ø€ åÐPÐP V¨V°VÐ$<ÐPÑPÔPÑQÔQˆØˆà�aŠ<ˆ<Ø-ˆMˆMØ˜Š\ˆ\Ø%ˆMˆMØ˜Š\ˆ\Ø'ˆMÝ7¸ÐG_Ñ`Ô`ÐØð 	,Ø'Ð'à+Ð+r)   Né   r   ÚxÚyÚzc                ó   •— g | ]}|‰v¯|‘Œ	S r$   r$   ©r%   r{   ÚgraphRemoves     €r'   r(   z"getPlotsToMake.<locals>.<listcomp>d  ó#   ø€ ÐLÐLÐL !°qÀÐ7KÐ7K˜AÐ7KÐ7KÐ7Kr)   rm   FTc                ó   •— g | ]}|‰v¯|‘Œ	S r$   r$   r   s     €r'   r(   z"getPlotsToMake.<locals>.<listcomp>z  r�   r)   r   )r   r\   r?   ÚaxesClassesr8   ra   rq   ÚitemsÚcollectionsÚOrderedDictrc   )rX   rv   rw   rx   ry   ÚgraphClassesÚ
axisLetterr]   ÚgcÚaxisObjClassÚgraphClassesFilteredÚ_axisLetterÚfoundÚunused_axisLetterÚaxisDictrd   ÚfilteredClassesr€   s    ```             @r'   ÚgetPlotsToMaker‘   í   sm  øøøø€ ðT,ð ,ð ,ð ,ð ,ð ,ð ,ð" 	�V˜V VÐ,°°¸±
Ò:Ð:Ø!ˆð Õ)Ð)Ð)Ý+¨KÔ8Ð9ˆˆå/°Ñ<Ô<ˆð ð (˜Kð (Ø!,¨f°fÐˆ�˜ØˆÝ%Ñ'Ô'ˆð €KØ#&¨ -°#°v°ÀÀfÀÐ!Nð 	'ð 	'Ñˆ
�IØð 	'ð 	'ˆBØÐ ØØ ¤Ð/Ð/Ø×"Ò" 2Ñ&Ô&Ð&ØØœ>¨*Ô5ˆLÝ# L°)Ñ<Ô<ð 'Ø×"Ò" 2Ñ&Ô&Ð&øð	'ð MÐLÐLÐL |ÐLÑLÔLÐØð 7Øð 	7�#Ð2Ñ3Ô3°qÒ8Ð8Ø'Ð'à �=Ð!5Ñ6Ô6Ð6ð €KØ$'¨ =°3¸°-À#ÀvÀÐ"Oð 'ð 'Ñˆ�YØð 
	'ð 
	'ˆBØÐ ØØˆEØ35´>×3GÒ3GÑ3IÔ3Ið ð Ñ/Ð! <Ý# L°)Ñ<Ô<ð Ø �EØ�Eðð ð 'Ø×"Ò" 2Ñ&Ô&Ð&øð
	'ð MÐLÐLÐL |ÐLÑLÔLÐØð 7Øð 	7�#Ð2Ñ3Ô3°qÒ8Ð8Ø'Ð'à �=Ð!5Ñ6Ô6Ð6õ Ô&Ñ(Ô(€HØ#&¨ -°#°v°ÀÀfÀÐ!Nð )ð )Ñˆ
�IØÐØÝ)¨)Ñ4Ô4ˆ	ØÐØØ(ˆ�ÑÐå
ˆ<ÑÔ˜AÒÐØ˜a” (Ð+Ð,Ð,à'˜-¨Ñ5Ô5ˆàð 	1Ø$ QÔ'¨Ð2Ð3Ð3à! !”_ hÐ/Ð0Ð0r)   c                  ó   — e Zd Zd„ Zd„ ZdS )ÚTestc                ó,  — t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          ¦   «         }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         t          d	dd
¦  «        }|                      |t          j	        g¦  «         t          d	dd¦  «        }|                      |t          j
        g¦  «         d S )Nr   r
   ÚdurationÚquarterLengthÚpsÚpitchÚ
pitchspaceÚ
pitchClassr   ÚqlÚpcÚoffset)r‘   ÚassertEqualr   ÚWindowedAmbitusÚWindowedKeyÚHorizontalBarPitchSpaceOffsetÚHistogramQuarterLengthÚHistogramPitchSpaceÚHistogramPitchClassÚScatterPitchSpaceQuarterLengthÚScatterPitchClassOffset©ÚselfÚposts     r'   ÚtestGetPlotsToMakeAzTest.testGetPlotsToMakeA˜  sÕ  € Ý˜iÑ(Ô(ˆØ×Ò˜¥Ô 4Ð5Ñ6Ô6Ð6Ý˜eÑ$Ô$ˆØ×Ò˜¥Ô 0Ð1Ñ2Ô2Ð2õ ÑÔˆØ×Ò˜¥Ô BÐCÑDÔDÐDõ ˜jÑ)Ô)ˆØ×Ò˜¥Ô ;Ð<Ñ=Ô=Ð=Ý˜oÑ.Ô.ˆØ×Ò˜¥Ô ;Ð<Ñ=Ô=Ð=Ý˜dÑ#Ô#ˆØ×Ò˜¥Ô 8Ð9Ñ:Ô:Ð:Ý˜gÑ&Ô&ˆØ×Ò˜¥Ô 8Ð9Ñ:Ô:Ð:Ý˜lÑ+Ô+ˆØ×Ò˜¥Ô 8Ð9Ñ:Ô:Ð:Ý˜lÑ+Ô+ˆØ×Ò˜¥Ô 8Ð9Ñ:Ô:Ð:å˜i¨°$Ñ7Ô7ˆØ×Ò˜¥Ô CÐDÑEÔEÐEå˜i¨¨xÑ8Ô8ˆØ×Ò˜¥Ô <Ð=Ñ>Ô>Ð>Ð>Ð>r)   c                óÆ   — t          d¦  «        }|                      |t          j        g¦  «         t          d¦  «        }|                      |t          j        g¦  «         d S )Nr   r	   )r‘   rž   r   ÚDolanr§   s     r'   ÚtestGetPlotsToMakeBzTest.testGetPlotsToMakeB¶  sV   € Ý˜gÑ&Ô&ˆØ×Ò˜¥¤
˜|Ñ,Ô,Ð,Ý˜mÑ,Ô,ˆØ×Ò˜¥¤
˜|Ñ,Ô,Ð,Ð,Ð,r)   N)Ú__name__Ú
__module__Ú__qualname__rª   r­   r$   r)   r'   r“   r“   —  s2   € € € € € ð?ð ?ð ?ð<-ð -ð -ð -ð -r)   r“   Ú__main__)r*   r+   )r*   r@   )FN)N)r]   r^   r*   r_   )rd   re   r]   r^   r*   rf   )NNNN)rX   ri   )!Ú__doc__Ú
__future__r   r…   r3   ÚunittestÚtypingr9   Úmusic21.graphr   r   r   rŸ   r¬   r    r¡   r   Ú__annotations__r"   ÚFORMATSr?   rE   rM   rU   r\   rc   ra   r‘   ÚTestCaser“   r®   Úmusic21ÚmainTestr$   r)   r'   ú<module>r¼      s  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð à Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø $Ð $Ð $Ð $Ð $Ð $ð Ô#ØŒZØ”:ØÔØÔ3ð>ð >Ð ð ð ð ñ ð*ð *ð *€ð ð ð ñ ð .Ð
-˜_Ð
-Ñ
-Ô
-€ðð ð ð ð2ð ð ð ð*ð ð ð ð:ð ð ð<ð ð ð ð8ð ð ð ð.ð ð ð ð> ,0ØØØðg1ð g1ð g1ð g1ð g1ðT#-ð #-ð #-ð #-ð #-ˆ8Ôñ #-ô #-ð #-ðL ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr)   