§
    „ØjC  ã                  óJ  — d Z ddlmZ ddlmZ ddlZddlZddlm	Z	 ddl
mZ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        rddlmZ ddddddœd4d„Zddddd œd5d&„Zdd'œd6d+„Zddd,œd7d0„Z G d1„ d2ej        ¦  «        Zed3k    rddlZ ej        e¦  «         dS dS )8zG
Tools for creating timespans (fast, manipulable objects) from Streams
é    )Úannotations)ÚSequenceN)ÚMusic21Object)Ú
M21ObjTypeÚ
StreamType)Úcommon)Únote)Úspans)ÚtimespanTree)Útrees©Ústream© ç        F)Ú
classListsÚcurrentParentageÚinitialOffsetÚflattenÚuseTimespansÚinputStreamr   r   ú$Sequence[Sequence[type[M21ObjType]]]r   ú tuple[stream.Stream, ...] | Noner   Úfloatr   ú
bool | strr   ÚboolÚreturnú2list[trees.OffsetTree | timespanTree.TimespanTree]c          
     ó"  ‡‡— ddl m} |€| f}|d         Š|rt          j        Šnt          j        Š|s ‰‰¬¦  «        g}nˆˆfd„|D ¦   «         }| j        dd…         | j        z   }|D �]¤}	‰                     |	¦  «        |z   }
d}|	j	        r’t          j        d|	¦  «        }	||	fz   }t          |	||
|||¬	¦  «        }t          ||¦  «        D ]O\  }}|dur|                     |dd…         ¦  «         Œ'|                     |                     ¦   «         |¦  «         ŒPd
}|r|dk    ræ|}|‰j        j        z   }|
|	j        j        z   }t          ||¦  «        D ]µ\  }}|r|	j                             |¦  «        rŒ"|r{t)          |	t*          j        |j        f¦  «        rt0          j        }nt0          j        } ||	t7          t9          |¦  «        ¦  «        |||
|¬¦  «        }|                     |¦  «         ŒŸ|                     |
|	¦  «         Œ¶�Œ¦|S )aß  
    To be DEPRECATED in v11: this is no faster than calling streamToTimespanTree
    multiple times with different classLists.

    Recurses through `inputStream`, and constructs TimespanTrees for each
    encountered substream and PitchedTimespan for each encountered non-stream
    element.

    `classLists` should be a sequence of elements contained in `classSet`. One
    TimespanTree will be constructed for each element in `classLists`, in
    a single optimized pass through the `inputStream`.

    This is used internally by `streamToTimespanTree`.

    >>> score = tree.examples.makeExampleScore()

    Get everything in the score

    >>> treeList = tree.fromStream.listOfTreesByClass(score, useTimespans=True)
    >>> treeList
    [<TimespanTree {2} (-inf to inf) <music21.stream.Score ...>>]
    >>> tl0 = treeList[0]
    >>> for t in tl0:
    ...     print(t)
    <TimespanTree {4} (-inf to inf) <music21.stream.Part ...>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 1 offset=0.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 2 offset=2.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 3 offset=4.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 4 offset=6.0>>
    <TimespanTree {4} (-inf to inf) <music21.stream.Part ...>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 1 offset=0.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 2 offset=2.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 3 offset=4.0>>
        <TimespanTree {0} (-inf to inf) <music21.stream.Measure 4 offset=6.0>>

    Now filter the Notes and the Clefs & TimeSignatures of the score
    (flattened) into a list of two TimespanTrees

    >>> classLists = ((note.Note,), (clef.Clef, meter.TimeSignature))
    >>> treeList = tree.fromStream.listOfTreesByClass(score, useTimespans=True,
    ...                                               classLists=classLists, flatten=True)
    >>> treeList
    [<TimespanTree {12} (0.0 to 8.0) <music21.stream.Score ...>>,
     <TimespanTree {4} (0.0 to 0.0) <music21.stream.Score ...>>]

    * Changed in v8: it is now a stickler that classLists must be sequences of sequences,
        such as tuples of tuples.
    r   r   Néÿÿÿÿ©Úsourcec                ó(   •— g | ]} ‰‰¬ ¦  «        ‘ŒS )r    r   )Ú.0Ú_ÚlastParentageÚ	treeClasss     €€úŒ/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/tree/fromStream.pyú
<listcomp>z&listOfTreesByClass.<locals>.<listcomp>j   s&   ø€ ÐKÐKÐK¸1�y�y¨Ð6Ñ6Ô6ÐKÐKÐKó    Fzmusic21.stream.Stream)r   r   r   r   r   TÚsemiFlat©ÚelementÚ	parentageÚparentOffsetÚparentEndTimeÚoffsetÚendTime)Úmusic21r   r   ÚTimespanTreer   Ú
OffsetTreeÚ	_elementsÚ_endElementsÚelementOffsetÚisStreamÚtÚcastÚlistOfTreesByClassÚzipÚinsertÚlowestPositionÚdurationÚquarterLengthÚclassSetÚ
isdisjointÚ
isinstancer	   ÚNotRestÚStreamr
   ÚPitchedTimespanÚElementTimespanÚtupleÚreversed)r   r   r   r   r   r   r   ÚoutputTreesÚinputStreamElementsr,   r0   Ú	wasStreamÚlocalParentageÚcontainedTreesÚ
outputTreeÚsubTreer.   r/   r1   ÚclassBasedTreeÚ	classListÚ	spanClassÚelementTimespanr%   r&   s                          @@r'   r;   r;       s·  øø€ ðt ÐÐÐÐÐàÐØ'˜>Ðà$ RÔ(€Mð ð %Ý Ô-ˆ	ˆ	åÔ$ˆ	àð LØ �y¨Ð6Ñ6Ô6Ð7ˆˆàKÐKÐKÐKÐKÀ
ÐKÑKÔKˆà%Ô/°°°Ô2°[Ô5MÑMÐØ&ð *;ñ *;ˆØ×,Ò,¨WÑ5Ô5¸ÑEˆØˆ	àÔð 	Ý”fÐ4°gÑ>Ô>ˆGØ-°°
Ñ:ˆNÝ/°ØAOØ>DØ8?Ø;EØ=IðKñ Kô KˆNõ (+¨;¸Ñ'GÔ'Gð Ið IÑ#�
˜GØ %Ð'Ð'Ø×%Ò% g¨a¨a¨a¤jÑ1Ô1Ð1Ð1à×%Ò% g×&<Ò&<Ñ&>Ô&>ÀÑHÔHÐHÐHØˆIàð 	;˜G zÒ1Ð1Ø(ˆLØ)¨MÔ,BÔ,PÑPˆMØ˜wÔ/Ô=Ñ=ˆGå-0°¸jÑ-IÔ-Ið ;ð ;Ñ)� 	Øð  Ô!1×!<Ò!<¸YÑ!GÔ!Gð ØØð ;å! '­D¬L¸&¼-Ð+HÑIÔIð :Ý$)Ô$9˜	˜	å$)Ô$9˜	Ø&/ i¸Ý:?ÅÐIYÑ@ZÔ@ZÑ:[Ô:[Ø=IØ>KØ7=Ø8?ð'Añ 'Aô 'A�Oð #×)Ò)¨/Ñ:Ô:Ð:Ð:à"×)Ò)¨&°'Ñ:Ô:Ð:Ð:ùàÐr)   )r   rR   r   ÚgroupOffsetsút.Literal['semiFlat'] | boolrR   úSequence[type] | NonerU   ú@trees.OffsetTree | trees.ElementTree | timespanTree.TimespanTreec               óH  ‡‡‡‡‡‡— 	 dˆˆˆˆˆˆfd„	Š‰rt           j        Šn‰du rt          j        Šnt          j        Š| j        s| j        r|                      ¦   «          | j        r-‰du r)| j        s‰du r ‰| ¬¦  «        }t          | |‰¬¦  «        S  ‰| | fd¬¦  «        S )	a@	  
    Converts a Stream and constructs an :class:`~music21.tree.trees.ElementTree` based on this.

    Use Stream.asTree() generally since that caches the ElementTree.

    >>> score = tree.examples.makeExampleScore()
    >>> elementTree = tree.fromStream.asTree(score)
    >>> elementTree
    <ElementTree {2} (0.0 <0.-20...> to 8.0) <music21.stream.Score exampleScore>>
    >>> for x in elementTree.iterNodes():
    ...     x
    <ElementNode: Start:0.0 <0.-20...> Indices:(l:0 *0* r:1) Payload:<music21.stream.Part ...>>
    <ElementNode: Start:0.0 <0.-20...> Indices:(l:0 *1* r:2) Payload:<music21.stream.Part ...>>

    >>> etFlat = tree.fromStream.asTree(score, flatten=True)
    >>> etFlat
    <ElementTree {20} (0.0 <0.-25...> to 8.0) <music21.stream.Score exampleScore>>

    The elementTree's classSortOrder has changed to -25 to match the lowest positioned element
    in the score, which is an Instrument object (classSortOrder=-25)

    >>> for x in etFlat.iterNodes():
    ...     x
    <ElementNode: Start:0.0 <0.-25...> Indices:(l:0 *0* r:2)
        Payload:<music21.instrument.Instrument 'PartA: : '>>
    <ElementNode: Start:0.0 <0.-25...> Indices:(l:1 *1* r:2)
        Payload:<music21.instrument.Instrument 'PartB: : '>>
    <ElementNode: Start:0.0 <0.0...> Indices:(l:0 *2* r:4) Payload:<music21.clef.BassClef>>
    <ElementNode: Start:0.0 <0.0...> Indices:(l:3 *3* r:4) Payload:<music21.clef.BassClef>>
    ...
    <ElementNode: Start:0.0 <0.20...> Indices:(l:5 *6* r:8) Payload:<music21.note.Note C>>
    <ElementNode: Start:0.0 <0.20...> Indices:(l:7 *7* r:8) Payload:<music21.note.Note C#>>
    <ElementNode: Start:1.0 <0.20...> Indices:(l:0 *8* r:20) Payload:<music21.note.Note D>>
    ...
    <ElementNode: Start:7.0 <0.20...> Indices:(l:15 *17* r:20) Payload:<music21.note.Note C>>
    <ElementNode: Start:End <0.-5...> Indices:(l:18 *18* r:20)
        Payload:<music21.bar.Barline type=final>>
    <ElementNode: Start:End <0.-5...> Indices:(l:19 *19* r:20)
        Payload:<music21.bar.Barline type=final>>

    >>> etFlat.getPositionAfter(0.5)
    SortTuple(atEnd=0, offset=1.0, priority=0, classSortOrder=20, isNotGrace=1, insertIndex=...)

    >>> etFlatNotes = tree.fromStream.asTree(score, flatten=True, classList=(note.Note,))
    >>> etFlatNotes
    <ElementTree {12} (0.0 <0.20...> to 8.0) <music21.stream.Score exampleScore>>

    Nc           	     óÚ  •— |d         }|€ ‰|¬¦  «        }| j         d d …         | j        z   }||j        j        z   }|D �])}t	          j        |                     |¦  «        |z   ¦  «        }|j        r ‰dur||fz   }	 ‰||	||¬¦  «         ‰dk    rŒT‰r|j         	                    ‰¦  «        rŒq‰rY||j        j        z   }
t          j        |t          t          |¦  «        ¦  «        ||||
¬¦  «        }|                     |¦  «         ŒÌ‰du rC|                     |¦  «        }|                     |¬¦  «        }|                     ||¦  «         �Œ|                     ||¦  «         �Œ+|S )Nr   r    F)r   r   Úinner_outputTreer*   r+   )r0   )r5   r6   r?   r@   r   ÚopFracr7   r8   rA   rB   r
   rF   rH   rI   r=   Ú	sortTupleÚmodify)ÚinnerStreamr   r   r[   r%   ÚinnerStreamElementsr/   r,   Ú
flatOffsetrM   r1   ÚpitchedTimespanÚpositionÚflatPositionrR   r   rU   ÚrecurseGetTreeByClassr&   r   s                 €€€€€€r'   re   z%asTree.<locals>.recurseGetTreeByClassÔ   sÖ  ø€ ð
 )¨Ô,ˆàÐ#Ø(˜y°Ð>Ñ>Ô>Ðð *Ô3°A°A°AÔ6¸Ô9QÑQÐØ%¨Ô(>Ô(LÑLˆà*ð 	=ñ 	=ˆGÝœ }×'BÒ'BÀ7Ñ'KÔ'KÈmÑ'[Ñ\Ô\ˆJàÔð  G°5Ð$8Ð$8Ø!1°W°JÑ!>�Ø%Ð% gØ7EØ4>Ø7GðIñ Iô Ið Ið ˜jÒ(Ð(Øàð ˜WÔ-×8Ò8¸ÑCÔCð Øàð =Ø$ wÔ'7Ô'EÑE�Ý"'Ô"7Ø#Ý#¥HÐ-=Ñ$>Ô$>Ñ?Ô?Ø!.Ø"/Ø%Ø#ð#%ñ #%ô #%�ð !×'Ò'¨Ñ8Ô8Ð8Ð8Ø Ð&Ð&à"×,Ò,¨]Ñ;Ô;�Ø'Ÿš°j˜ÑAÔA�Ø ×'Ò'¨°gÑ>Ô>Ð>Ñ>à ×'Ò'¨
°GÑ<Ô<Ð<Ñ<àÐr)   Fr    )rO   rR   r   )r   r   )N)
r   r3   r   ÚElementTreer4   ÚisSortedÚautoSortÚsortÚisFlatÚ#makeFastShallowTreeFromSortedStream)r   r   rR   r   rU   rO   re   r&   s    ```` @@r'   ÚasTreerl   œ   s)  øøøøøø€ ðx "ð	/ ð / ð / ð / ð / ð / ð / ð / ð / ð / ð / ðh ð %Ý Ô-ˆ	ˆ	Ø	˜Ð	Ð	ÝÔ%ˆ	ˆ	åÔ$ˆ	ð Ôð  KÔ$8ð Ø×ÒÑÔÐð 	Ôð 
8Ø Ð%Ð%ØÔ#ð &Ø'.°%Ð'7Ð'7Ø9B¸È+Ð9VÑ9VÔ9Vˆ
Ý2°;Ø>HØ=FðHñ Hô Hð 	Hð %Ð$ [Ø7B°nØ36ð8ñ 8ô 8ð 	8r)   )rR   ústream.StreamrO   ú$trees.OffsetTree | trees.ElementTreec               óâ   ‡ ‡— ‰ j         dd…         ‰ j        z   }‰€ˆ fd„|D ¦   «         }nˆˆ fd„|D ¦   «         }|                     |¦  «         |j        �|j                             ¦   «          |S )a&  
    Use populateFromSortedList to quickly make a tree from a stream.

    This only works if the stream is flat (or we are not flattening) and
    sorts have already been run, and we are not making an OffsetTree.

    Returns the same outputTree that was put in, only with elements in it.
    Nc                ó>   •— g | ]}|                      ‰¦  «        |f‘ŒS r   )r]   )r#   Úer   s     €r'   r(   z7makeFastShallowTreeFromSortedStream.<locals>.<listcomp>2  s*   ø€ ÐWÐWÐW¸a˜QŸ[š[¨Ñ5Ô5°qÐ9ÐWÐWÐWr)   c                ór   •— g | ]3}|j                              ‰¦  «        °|                     ‰¦  «        |f‘Œ4S r   )rA   rB   r]   )r#   rq   rR   r   s     €€r'   r(   z7makeFastShallowTreeFromSortedStream.<locals>.<listcomp>4  sU   ø€ ð Eð Eð E¸aØ#$¤:×#8Ò#8¸Ñ#CÔ#CðE˜QŸ[š[¨Ñ5Ô5°qÐ9ð Eð Eð Er)   )r5   r6   ÚpopulateFromSortedListÚrootNodeÚupdateEndTimes)r   rO   rR   rK   ÚelementTupleLists   ` `  r'   rk   rk   !  s³   øø€ ð &Ô/°°°Ô2°[Ô5MÑMÐàÐØWÐWÐWÐWÐCVÐWÑWÔWÐÐðEð Eð Eð Eð EÐCVð Eñ Eô EÐà×%Ò%Ð&6Ñ7Ô7Ð7ØÔÐ&ØÔ×*Ò*Ñ,Ô,Ð,ØÐr)   )r   rR   ú
str | boolú$Sequence[type[Music21Object]] | NoneútimespanTree.TimespanTreec               ó¬   — |€
t           gg}n|g}t          | d||d¬¦  «        }|d         }t          j        rt	          |t
          j        ¦  «        sJ ‚|S )ac  
    Recurses through a score and constructs a
    :class:`~music21.tree.trees.TimespanTree`.  Use Stream.asTimespans() generally
    since that caches the TimespanTree.

    >>> score = corpus.parse('bwv66.6')
    >>> scoreTree = tree.fromStream.asTimespans(score, flatten=True,
    ...                                         classList=(note.Note, chord.Chord))
    >>> scoreTree
    <TimespanTree {165} (0.0 to 36.0) <music21.stream.Score ...>>
    >>> for x in scoreTree[:5]:
    ...     x
    ...
    <PitchedTimespan (0.0 to 0.5) <music21.note.Note C#>>
    <PitchedTimespan (0.0 to 0.5) <music21.note.Note A>>
    <PitchedTimespan (0.0 to 0.5) <music21.note.Note A>>
    <PitchedTimespan (0.0 to 1.0) <music21.note.Note E>>
    <PitchedTimespan (0.5 to 1.0) <music21.note.Note B>>

    >>> scoreTree = tree.fromStream.asTimespans(score, flatten=False, classList=())

    Each of these has 11 elements -- mainly the Measures

    >>> for x in scoreTree:
    ...     x
    ...
    <ElementTimespan (0.0 to 0.0) <music21.metadata.Metadata object at 0x...>>
    <ElementTimespan (0.0 to 0.0) <music21.layout.StaffGroup ...>>
    <TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Soprano>>
    <TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Alto>>
    <TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Tenor>>
    <TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Bass>>

    >>> tenorElements = scoreTree[4]
    >>> tenorElements
    <TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Tenor>>

    >>> tenorElements.source
    <music21.stream.Part Tenor>

    >>> tenorElements.source is score[3]
    True
    Nr   T)r   r   r   r   r   )r   r;   r9   ÚTYPE_CHECKINGrC   r   r3   )r   r   rR   r   ÚlistOfTimespanTreesÚtimespanTreeFirsts         r'   ÚasTimespansr~   <  s|   € ðd ÐÝ$�oÐ&ˆ
ˆ
à�[ˆ
Ý,¨[Ø;>Ø5<Ø8BØ:>ð	@ñ @ô @Ðð
 ,¨AÔ.ÐÝ„ð HÝÐ+­\Ô-FÑGÔGÐGÐGÐGØÐr)   c                  ó   — e Zd Zd„ Zd„ ZdS )ÚTestc                óä  — ddl m} |                     d¦  «                             ¦   «         }|                     ¦   «         }d|_        i |_        |                     ¦   «         }|                      t          |¦  «        t          |¦  «        ¦  «         |                      t          |¦  «        t          |¦  «        ¦  «         t          ||¦  «        D ]\  }}|  
                    ||¦  «         ŒdS )z]
        tests that the isSorted speed up trick ends up producing identical results.
        r   )Úcorpuszbwv66.6FN)r2   r‚   Úparser   rl   rg   Ú_cacheÚassertEqualÚlenr<   ÚassertIs)Úselfr‚   ÚsfÚsfTreeÚ
sfTreeSlowÚfastIÚslowIs          r'   ÚtestFastPopulatezTest.testFastPopulate€  sß   € ð 	#Ð"Ð"Ð"Ð"Ð"Ø�\Š\˜)Ñ$Ô$×,Ò,Ñ.Ô.ˆØ—’‘”ˆð ˆŒØˆŒ	Ø—Y’Y‘[”[ˆ
Ø×Ò�˜R™œ¥# j¡/¤/Ñ2Ô2Ð2Ø×Ò�˜R™œ¥# f¡+¤+Ñ.Ô.Ð.Ý ¨
Ñ3Ô3ð 	(ð 	(‰LˆE�5Ø�MŠM˜% Ñ'Ô'Ð'Ð'ð	(ð 	(r)   c                ó¢   — ddl m}  |¦   «         }|                     ¦   «          t          |¦  «        }|                      |j        d¦  «         d S )Nr   )ÚmakeExampleScoreg       @)Úmusic21.tree.examplesr�   ri   rl   r…   r1   )rˆ   r�   ÚscÚscTrees       r'   ÚtestAutoSortExamplezTest.testAutoSortExample‘  sX   € Ø:Ð:Ð:Ð:Ð:Ð:ØÐÑÔˆØ
�Š‰	Œ	ˆ	Ý˜‘”ˆØ×Ò˜œ¨Ñ-Ô-Ð-Ð-Ð-r)   N)Ú__name__Ú
__module__Ú__qualname__rŽ   r”   r   r)   r'   r€   r€   ~  s2   € € € € € ð(ð (ð (ð".ð .ð .ð .ð .r)   r€   Ú__main__)r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   rV   rR   rW   r   r   rU   r   r   rX   )r   rm   rO   rn   rR   rW   r   rn   )r   rw   rR   rx   r   ry   )Ú__doc__Ú
__future__r   Úcollections.abcr   Útypingr9   ÚunittestÚmusic21.baser   Úmusic21.common.typesr   r   r2   r   r	   Úmusic21.treer
   r   r   r{   r   r;   rl   rk   r~   ÚTestCaser€   r•   ÚmainTestr   r)   r'   ú<module>r£      s  ððð ð #Ð "Ð "Ð "Ð "Ð "à $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ø €€€à &Ð &Ð &Ð &Ð &Ð &Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø %Ð %Ð %Ð %Ð %Ð %Ø Ð Ð Ð Ð Ð à„?ð ØÐÐÐÐÐð 8:Ø7;ØØØðyð yð yð yð yð yð~ +0Ø%)ØØðC8ð C8ð C8ð C8ð C8ð C8ðR &*ð	ð ð ð ð ð ð< Ø48ð	>ð >ð >ð >ð >ð >ðD.ð .ð .ð .ð .ˆ8Ôñ .ô .ð .ð< ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr)   