§
    º³Ùg¹1  ã                   óD  — d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
 ddlZddlmZ ddlmZ ddlmZ deej        j                 d	eeef         d
edeeeeej        j                 f                  fd„Zdeej        j                 d	eeef         d
edeeeeej        j                 f                  fd„Zdeej        j                 d	eeef         d
edeeeeej        j                 f                  fd„Zdeej        j                 d	eeef         d
edeeeeej        j                 f                  fd„Z	 ddeeef         deeeef                  de	e         dej        fd„Zde
ej        ej        f         d
edefd„Z de
ej        ej        f         d
edefd„Z!dS )a!	  
A collection of functions that decide the layout of an output image.
See :py:mod:`~qiskit.visualization.pulse_v2.types` for more info on the required data.

There are 3 types of layout functions in this module.

1. layout.chart_channel_map

An end-user can write arbitrary functions that output the custom channel ordering
associated with group name. Layout function in this module are called with the
`formatter` and `device` kwargs. These data provides stylesheet configuration
and backend system configuration.

The layout function is restricted to:


    ```python
    def my_channel_layout(channels: List[pulse.channels.Channel],
                          formatter: Dict[str, Any],
                          device: DrawerBackendInfo
                          ) -> Iterator[Tuple[str, List[pulse.channels.Channel]]]:
        ordered_channels = []
        # arrange order of channels

        for key, channels in my_ordering_dict.items():
            yield key, channels
    ```

2. layout.time_axis_map

An end-user can write arbitrary functions that output the `HorizontalAxis` data set that
will be later consumed by the plotter API to update the horizontal axis appearance.
Layout function in this module are called with the `time_window`, `axis_breaks`, and `dt` kwargs.
These data provides horizontal axis limit, axis break position, and time resolution, respectively.

See py:mod:`qiskit.visualization.pulse_v2.types` for more info on the required
data.

    ```python
    def my_horizontal_axis(time_window: Tuple[int, int],
                           axis_breaks: List[Tuple[int, int]],
                           dt: Optional[float] = None) -> HorizontalAxis:
        # write horizontal axis configuration

        return horizontal_axis
    ```

3. layout.figure_title

An end-user can write arbitrary functions that output the string data that
will be later consumed by the plotter API to output the figure title.
Layout functions in this module are called with the `program` and `device` kwargs.
This data provides input program and backend system configurations.

    ```python
    def my_figure_title(program: Union[pulse.Waveform, pulse.Schedule],
                        device: DrawerBackendInfo) -> str:

        return 'title'
    ```

An arbitrary layout function satisfying the above format can be accepted.
é    )Údefaultdict)ÚListÚDictÚAnyÚTupleÚIteratorÚOptionalÚUnionN)Úpulse)Útypes)ÚDrawerBackendInfoÚchannelsÚ	formatterÚdeviceÚreturnc              #   ó  K  — t          t          ¦  «        }| D ]*}|t          |¦  «                                      |¦  «         Œ+g }|                     t
          j        g ¦  «        }|                     t          |d„ ¬¦  «        ¦  «         |                     t
          j	        g ¦  «        }|                     t          |d„ ¬¦  «        ¦  «         |                     t
          j
        g ¦  «        }|                     t          |d„ ¬¦  «        ¦  «         |d         rE|                     t
          j        g ¦  «        }	|                     t          |	d„ ¬¦  «        ¦  «         |D ] }|j                             ¦   «         |gfV — Œ!dS )a  Layout function for the channel assignment to the chart instance.

    Assign single channel per chart. Channels are grouped by type and
    sorted by index in ascending order.

    Stylesheet key:
        `chart_channel_map`

    For example:
        [D0, D2, C0, C2, M0, M2, A0, A2] -> [D0, D2, C0, C2, M0, M2, A0, A2]

    Args:
        channels: Channels to show.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Yields:
        Tuple of chart name and associated channels.
    c                 ó   — | j         S ©N©Úindex©Úxs    ú[/granary/edev/quantum/lib/python3.11/site-packages/qiskit/visualization/pulse_v2/layouts.pyú<lambda>z+channel_type_grouped_sort.<locals>.<lambda>w   ó   € ¸!¼'€ ó    ©Úkeyc                 ó   — | j         S r   r   r   s    r   r   z+channel_type_grouped_sort.<locals>.<lambda>{   r   r   c                 ó   — | j         S r   r   r   s    r   r   z+channel_type_grouped_sort.<locals>.<lambda>   r   r   úcontrol.show_acquire_channelc                 ó   — | j         S r   r   r   s    r   r   z+channel_type_grouped_sort.<locals>.<lambda>„   s   € ¸a¼g€ r   N)r   ÚlistÚtypeÚappendÚgetr   ÚDriveChannelÚextendÚsortedÚControlChannelÚMeasureChannelÚAcquireChannelÚnameÚupper)
r   r   r   Úchan_type_dictÚchanÚordered_channelsÚd_chansÚc_chansÚm_chansÚa_chanss
             r   Úchannel_type_grouped_sortr6   X   s’  è è € õ, !¥Ñ&Ô&€Nàð 0ð 0ˆØ•t˜D‘z”zÔ"×)Ò)¨$Ñ/Ô/Ð/Ð/àÐð × Ò ¥Ô!3°RÑ8Ô8€GØ×Ò�F 7Ð0AÐ0AÐBÑBÔBÑCÔCÐCð × Ò ¥Ô!5°rÑ:Ô:€GØ×Ò�F 7Ð0AÐ0AÐBÑBÔBÑCÔCÐCð × Ò ¥Ô!5°rÑ:Ô:€GØ×Ò�F 7Ð0AÐ0AÐBÑBÔBÑCÔCÐCð Ð/Ô0ð HØ ×$Ò$¥UÔ%9¸2Ñ>Ô>ˆØ×Ò¥ wÐ4EÐ4EÐ FÑ FÔ FÑGÔGÐGà ð (ð (ˆØŒi�oŠoÑÔ $ Ð'Ð'Ð'Ð'Ð'ð(ð (r   c              #   óN  K  — t          t          ¦  «        }t          ¦   «         }| D ]D}|t          |¦  «                                      |¦  «         |                     |j        ¦  «         ŒE|                     t          j	        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }	t          |	d„ d¬¦  «        }	g }
t          |¦  «        D �]7}t          |¦  «        dk    r8|d         j        |k    r'|
                     |                     ¦   «         ¦  «         t          |¦  «        dk    r8|d         j        |k    r'|
                     |                     ¦   «         ¦  «         t          |¦  «        dk    r8|d         j        |k    r'|
                     |                     ¦   «         ¦  «         |d	         rKt          |	¦  «        dk    r8|	d         j        |k    r'|
                     |	                     ¦   «         ¦  «         �Œ9|
D ] }|j                             ¦   «         |gfV — Œ!d
S )a	  Layout function for the channel assignment to the chart instance.

    Assign single channel per chart. Channels are grouped by the same index and
    sorted by type.

    Stylesheet key:
        `chart_channel_map`

    For example:
        [D0, D2, C0, C2, M0, M2, A0, A2] -> [D0, D2, C0, C2, M0, M2, A0, A2]

    Args:
        channels: Channels to show.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Yields:
        Tuple of chart name and associated channels.
    c                 ó   — | j         S r   r   r   s    r   r   z,channel_index_grouped_sort.<locals>.<lambda>¨   ó   € ¨A¬G€ r   T©r   Úreversec                 ó   — | j         S r   r   r   s    r   r   z,channel_index_grouped_sort.<locals>.<lambda>«   r9   r   c                 ó   — | j         S r   r   r   s    r   r   z,channel_index_grouped_sort.<locals>.<lambda>®   r9   r   c                 ó   — | j         S r   r   r   s    r   r   z,channel_index_grouped_sort.<locals>.<lambda>±   r9   r   r   éÿÿÿÿr!   N)r   r#   Úsetr$   r%   Úaddr   r&   r   r'   r)   r*   r+   r,   ÚlenÚpopr-   r.   )r   r   r   r/   Úindsr0   r2   Úu_chansr4   r5   r1   Úinds               r   Úchannel_index_grouped_sortrG   Š   s€  è è € õ, !¥Ñ&Ô&€NÝ‰5Œ5€Dàð ð ˆØ•t˜D‘z”zÔ"×)Ò)¨$Ñ/Ô/Ð/Ø�Š�”ÑÔÐÐà× Ò ¥Ô!3°RÑ8Ô8€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€GàÐå�d‰|Œ|ð 7ñ 7ˆåˆw‰<Œ<˜!ÒÐ ¨¤Ô 1°SÒ 8Ð 8Ø×#Ò# G§K¢K¡M¤MÑ2Ô2Ð2åˆw‰<Œ<˜!ÒÐ ¨¤Ô 1°SÒ 8Ð 8Ø×#Ò# G§K¢K¡M¤MÑ2Ô2Ð2åˆw‰<Œ<˜!ÒÐ ¨¤Ô 1°SÒ 8Ð 8Ø×#Ò# G§K¢K¡M¤MÑ2Ô2Ð2àÐ3Ô4ð 	7Ý�7‰|Œ|˜aÒÐ G¨B¤KÔ$5¸Ò$<Ð$<Ø ×'Ò'¨¯ª©¬Ñ6Ô6Ð6ùà ð (ð (ˆØŒi�oŠoÑÔ $ Ð'Ð'Ð'Ð'Ð'ð(ð (r   c              #   óÜ  K  — t          t          ¦  «        }t          ¦   «         }| D ]D}|t          |¦  «                                      |¦  «         |                     |j        ¦  «         ŒE|                     t          j	        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }t          |d„ d¬¦  «        }|                     t          j        g ¦  «        }	t          |	d„ ¬¦  «        }	g }
t          |¦  «        D ]ë}t          |¦  «        dk    r8|d	         j        |k    r'|
                     |                     ¦   «         ¦  «         t          |¦  «        dk    r8|d	         j        |k    r'|
                     |                     ¦   «         ¦  «         |d
         rKt          |¦  «        dk    r8|d	         j        |k    r'|
                     |                     ¦   «         ¦  «         Œì|
                     |	¦  «         |
D ] }|j                             ¦   «         |gfV — Œ!dS )ab  Layout function for the channel assignment to the chart instance.

    Assign single channel per chart. Channels are grouped by the same index and
    sorted by type except for control channels. Control channels are added to the
    end of other channels.

    Stylesheet key:
        `chart_channel_map`

    For example:
        [D0, D2, C0, C2, M0, M2, A0, A2] -> [D0, D2, C0, C2, M0, M2, A0, A2]

    Args:
        channels: Channels to show.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Yields:
        Tuple of chart name and associated channels.
    c                 ó   — | j         S r   r   r   s    r   r   z.channel_index_grouped_sort_u.<locals>.<lambda>ç   r9   r   Tr:   c                 ó   — | j         S r   r   r   s    r   r   z.channel_index_grouped_sort_u.<locals>.<lambda>ê   r9   r   c                 ó   — | j         S r   r   r   s    r   r   z.channel_index_grouped_sort_u.<locals>.<lambda>í   r9   r   c                 ó   — | j         S r   r   r   s    r   r   z.channel_index_grouped_sort_u.<locals>.<lambda>ð   r9   r   r   r   r?   r!   N)r   r#   r@   r$   r%   rA   r   r&   r   r'   r)   r+   r,   r*   rB   rC   r(   r-   r.   )r   r   r   r/   rD   r0   r2   r4   r5   rE   r1   rF   s               r   Úchannel_index_grouped_sort_urM   È   sV  è è € õ. !¥Ñ&Ô&€NÝ‰5Œ5€Dàð ð ˆØ•t˜D‘z”zÔ"×)Ò)¨$Ñ/Ô/Ð/Ø�Š�”ÑÔÐÐà× Ò ¥Ô!3°RÑ8Ô8€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3¸TÐBÑBÔB€Gà× Ò ¥Ô!5°rÑ:Ô:€GÝ�WÐ"3Ð"3Ð4Ñ4Ô4€GàÐå�d‰|Œ|ð 
7ð 
7ˆåˆw‰<Œ<˜!ÒÐ ¨¤Ô 1°SÒ 8Ð 8Ø×#Ò# G§K¢K¡M¤MÑ2Ô2Ð2åˆw‰<Œ<˜!ÒÐ ¨¤Ô 1°SÒ 8Ð 8Ø×#Ò# G§K¢K¡M¤MÑ2Ô2Ð2àÐ3Ô4ð 	7Ý�7‰|Œ|˜aÒÐ G¨B¤KÔ$5¸Ò$<Ð$<Ø ×'Ò'¨¯ª©¬Ñ6Ô6Ð6øð ×Ò˜GÑ$Ô$Ð$à ð (ð (ˆØŒi�oŠoÑÔ $ Ð'Ð'Ð'Ð'Ð'ð(ð (r   c              #   óŠ  K  — t           j        j        t           j        j        t           j        j        f}t          t          ¦  «        }| D ]A}t          ||¦  «        rŒ||                     |¦  «                  	                    |¦  «         ŒBt          |                     ¦   «         d„ ¬¦  «        }|D ]\  }}d|d›�|fV — ŒdS )aV  Layout function for the channel assignment to the chart instance.

    Assign multiple channels per chart. Channels associated with the same qubit
    are grouped in the same chart and sorted by qubit index in ascending order.

    Acquire channels are not shown.

    Stylesheet key:
        `chart_channel_map`

    For example:
        [D0, D2, C0, C2, M0, M2, A0, A2] -> [Q0, Q1, Q2]

    Args:
        channels: Channels to show.
        formatter: Dictionary of stylesheet settings.
        device: Backend configuration.

    Yields:
        Tuple of chart name and associated channels.
    c                 ó   — | d         S )Nr   © r   s    r   r   z"qubit_index_sort.<locals>.<lambda>,  s
   € ÀÀ1Ä€ r   r   ÚQÚdN)r   r   r,   Ú
MemorySlotÚRegisterSlotr   r#   Ú
isinstanceÚget_qubit_indexr%   r)   Úitems)	r   r   r   Ú_removedÚqubit_channel_mapr0   Ú
sorted_mapÚqindÚchanss	            r   Úqubit_index_sortr]     sá   è è € õ2 	ŒÔ%ÝŒÔ!ÝŒÔ#ð€Hõ $¥DÑ)Ô)Ðàð Eð EˆÝ�d˜HÑ%Ô%ð 	ØØ˜&×0Ò0°Ñ6Ô6Ô7×>Ò>¸tÑDÔDÐDÐDåÐ)×/Ò/Ñ1Ô1°~°~ÐFÑFÔF€Jà!ð "ð "‰ˆˆeØ�$ˆlˆlˆl˜EÐ!Ð!Ð!Ð!Ð!ð"ð "r   Útime_windowÚaxis_breaksÚdtc           	      ó"  — | \  }}|}|}g }d}|D ]N\  }	}
|
|k     s|	|k    rŒ||
k    r||
|	z
  z  }||
k    r||
|	z
  z  }|                      |	|z
  ¦  «         ||
|	z
  z  }ŒOt          j        t          |d¦  «        |d¦  «        }|                     ¦   «         }|D ]'\  }	}
|
|	z
  }t          j        ||	k    ||z   |¦  «        }Œ(|rd}||dz  z  }nd}d„ |D ¦   «         }t          j        ||ft          t          ||¦  «        ¦  «        ||¬¦  «        S )a˜  Layout function for the horizontal axis formatting.

    Calculate axis break and map true time to axis labels. Generate equispaced
    6 horizontal axis ticks. Convert into seconds if ``dt`` is provided.

    Args:
        time_window: Left and right edge of this graph.
        axis_breaks: List of axis break period.
        dt: Time resolution of system.

    Returns:
        Axis formatter object.
    r   é   z	Time (ns)ç    eÍÍAzSystem cycle time (dt)c                 ó   — g | ]}|d ›‘ŒS )z.0frP   )Ú.0Úvals     r   ú
<listcomp>z"time_map_in_ns.<locals>.<listcomp>b  s   € Ð:Ð:Ð:¨˜#�|�|Ð:Ð:Ð:r   )ÚwindowÚaxis_mapÚaxis_break_posÚlabel)
r%   ÚnpÚlinspaceÚmaxÚcopyÚwherer   ÚHorizontalAxisÚdictÚzip)r^   r_   r`   Út0Út1Út0_shiftÚt1_shiftrj   Úoffset_accumulationÚt0bÚt1bÚaxis_locÚ
axis_labelÚoffsetrk   Úformatted_labels                   r   Útime_map_in_nsr   2  s€  € ð" �F€BˆØ€HØ€Hà€NØÐØð )ð )‰ˆˆSØ�Š8ˆ8�s˜R’x�xØØ�Š8ˆ8Ø˜˜c™	Ñ!ˆHØ�Š8ˆ8Ø˜˜c™	Ñ!ˆHØ×Ò˜cÐ$7Ñ7Ñ8Ô8Ð8Ø˜s S™yÑ(ÐÐõ Œ{�3˜x¨Ñ+Ô+¨X°qÑ9Ô9€HØ—’‘”€Jàð Qð Q‰ˆˆSØ�s‘ˆÝ”X˜j¨3Ò.°
¸VÑ0CÀZÑPÔPˆ
ˆ
ð 
ð )ØˆØ�b˜3‘hÑˆ
ˆ
à(ˆà:Ð:¨zÐ:Ñ:Ô:€OåÔØ˜(Ð#Ý•c˜( OÑ4Ô4Ñ5Ô5Ø%Øð	ñ ô ð r   Úprogramc                 ó:  — g }|                      d| j        › �¦  «         |j        r
|j        dz  nd}|                      d| j        |z  d›d|j        rdnd› �¦  «         |j        d	k    r|                      d
|j        › �¦  «         d                     |¦  «        S )zˆLayout function for generating figure title.

    This layout writes program name, program duration, and backend name in the title.
    zName: rc   g      ð?z
Duration: z.1fú Únsr`   z
no-backendz	Backend: z, )r%   r-   r`   ÚdurationÚbackend_nameÚjoin)r€   r   Ú	title_strr`   s       r   Údetail_titlerˆ   l  sÀ   € ð
 €Ið ×ÒÐ,˜gœlÐ,Ð,Ñ-Ô-Ð-ð #œIÐ	.ˆŒ�S‰ˆ¨3€BØ×ÒÐ[ 'Ô"2°RÑ"7Ð[Ð[Ð[ÀfÄiÐ>Y¸d¸dÐUYÐ[Ð[Ñ\Ô\Ð\ð Ô˜lÒ*Ð*Ø×ÒÐ: VÔ%8Ð:Ð:Ñ;Ô;Ð;à�9Š9�YÑÔÐr   c                 ó   — dS )z5Layout function for generating an empty figure title.Ú rP   )r€   r   s     r   Úempty_titler‹   �  s   € àˆ2r   r   )"Ú__doc__Úcollectionsr   Útypingr   r   r   r   r   r	   r
   Únumpyrl   Úqiskitr   Úqiskit.visualization.pulse_v2r   Ú)qiskit.visualization.pulse_v2.device_infor   r   ÚChannelÚstrr6   rG   rM   r]   ÚintÚfloatrq   r   ÚWaveformÚSchedulerˆ   r‹   rP   r   r   ú<module>r™      sö  ðð>ð >ð@ $Ð #Ð #Ð #Ð #Ð #Ø DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ DÐ Dà Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø /Ð /Ð /Ð /Ð /Ð /Ø GÐ GÐ GÐ GÐ GÐ Gð/(Ø�5”>Ô)Ô*ð/(Ø7;¸CÀ¸H´~ð/(ØO`ð/(àˆe�C˜˜eœnÔ4Ô5Ð5Ô6Ô7ð/(ð /(ð /(ð /(ðd;(Ø�5”>Ô)Ô*ð;(Ø7;¸CÀ¸H´~ð;(ØO`ð;(àˆe�C˜˜eœnÔ4Ô5Ð5Ô6Ô7ð;(ð ;(ð ;(ð ;(ð|<(Ø�5”>Ô)Ô*ð<(Ø7;¸CÀ¸H´~ð<(ØO`ð<(àˆe�C˜˜eœnÔ4Ô5Ð5Ô6Ô7ð<(ð <(ð <(ð <(ð~("Ø�5”>Ô)Ô*ð("Ø7;¸CÀ¸H´~ð("ØO`ð("àˆe�C˜˜eœnÔ4Ô5Ð5Ô6Ô7ð("ð ("ð ("ð ("ðX ]að7ð 7Ø�s˜C�x”ð7Ø/3°E¸#¸s¸(´OÔ/Dð7ØJRÐSXÌ/ð7à
Ôð7ð 7ð 7ð 7ðt ˜% ¤°´Ð >Ô?ð  ÐIZð  Ð_bð  ð  ð  ð  ð*˜˜uœ~¨u¬~Ð=Ô>ð ÐHYð Ð^að ð ð ð ð ð r   