§
    º³ÙgÑ ã                  ó®  — 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ZddlZddl	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZ ddlZddlmZmZ dd	lmZmZm Z m!Z!m"Z"m#Z#m$Z$ dd
l%m&Z& ddl'm(Z( ddl)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ej0        dk    rddlm1Z1 nddl2m1Z1  ej3        d¦  «        Z4de5d<    ed¦  «        Z6eej7        ej8        f         Z9d‰d„Z: G d„ d¦  «        Z;e/	 	 	 	 dŠd‹d#„¦   «         Z<dŒd$„Z=e/d%„ ¦   «         Z>d�d'„Z?dŽd*„Z@e/d�d,„¦   «         ZAe/d�d0„¦   «         ZBe/d‘d2„¦   «         ZCe/d’d5„¦   «         ZDd“d8„ZEee/d”d:„¦   «         ¦   «         ZFee/d”d;„¦   «         ¦   «         ZGee/d”d<„¦   «         ¦   «         ZHee/d•d?„¦   «         ¦   «         ZIee/d–dB„¦   «         ¦   «         ZJed—dE„¦   «         ZKee/d˜dJ„¦   «         ¦   «         ZLee/dKdLœd™dP„¦   «         ¦   «         ZMe/dšdR„¦   «         ZNe/d›dT„¦   «         ZOe/dœdV„¦   «         ZPe/d�dZ„¦   «         ZQe/dždŸd]„¦   «         ZRe/džd d`„¦   «         ZS G da„ dbedK¬c¦  «        ZTe/d¡dj„¦   «         ZUe/džd¢dk„¦   «         ZVe/džd¢dl„¦   «         ZWe/džd£dm„¦   «         ZXe/džd£dn„¦   «         ZYe/d¤d¥ds„¦   «         ZZe/	 	 d¦d§dz„¦   «         Z[e/d¨d|„¦   «         Z\e/dd}œd©d„¦   «         Z]dªd�„Z^e/	 džd«d…„¦   «         Z_e/d¬d‡„¦   «         Z`e/d­dˆ„¦   «         ZadS )®a0  

.. _pulse_builder:

=============
Pulse Builder
=============

..
    We actually want people to think of these functions as being defined within the ``qiskit.pulse``
    namespace, not the submodule ``qiskit.pulse.builder``.

.. currentmodule: qiskit.pulse

Use the pulse builder DSL to write pulse programs with an imperative syntax.

.. warning::
    The pulse builder interface is still in active development. It may have
    breaking API changes without deprecation warnings in future releases until
    otherwise indicated.


The pulse builder provides an imperative API for writing pulse programs
with less difficulty than the :class:`~qiskit.pulse.Schedule` API.
It contextually constructs a pulse schedule and then emits the schedule for
execution. For example, to play a series of pulses on channels is as simple as:


.. plot::
   :alt: Output from the previous code.
   :include-source:

   from qiskit import pulse

   dc = pulse.DriveChannel
   d0, d1, d2, d3, d4 = dc(0), dc(1), dc(2), dc(3), dc(4)

   with pulse.build(name='pulse_programming_in') as pulse_prog:
       pulse.play([1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1], d0)
       pulse.play([1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0], d1)
       pulse.play([1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0], d2)
       pulse.play([1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0], d3)
       pulse.play([1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0], d4)

   pulse_prog.draw()

To begin pulse programming we must first initialize our program builder
context with :func:`build`, after which we can begin adding program
statements. For example, below we write a simple program that :func:`play`\s
a pulse:

.. plot::
   :alt: Output from the previous code.
   :include-source:

   from qiskit import pulse

   d0 = pulse.DriveChannel(0)

   with pulse.build() as pulse_prog:
       pulse.play(pulse.Constant(100, 1.0), d0)

   pulse_prog.draw()

The builder initializes a :class:`.pulse.Schedule`, ``pulse_prog``
and then begins to construct the program within the context. The output pulse
schedule will survive after the context is exited and can be used like a
normal Qiskit schedule.

Pulse programming has a simple imperative style. This leaves the programmer
to worry about the raw experimental physics of pulse programming and not
constructing cumbersome data structures.

We can optionally pass a :class:`~qiskit.providers.Backend` to
:func:`build` to enable enhanced functionality. Below, we prepare a Bell state
by automatically compiling the required pulses from their gate-level
representations, while simultaneously applying a long decoupling pulse to a
neighboring qubit. We terminate the experiment with a measurement to observe the
state we prepared. This program which mixes circuits and pulses will be
automatically lowered to be run as a pulse program:

.. plot::
   :alt: Output from the previous code.
   :include-source:

   from math import pi
   from qiskit.compiler import schedule
   from qiskit.circuit import QuantumCircuit

   from qiskit import pulse
   from qiskit.providers.fake_provider import GenericBackendV2

   backend = GenericBackendV2(num_qubits=5, calibrate_instructions=True)

   d2 = pulse.DriveChannel(2)

   qc = QuantumCircuit(2)
   # Hadamard
   qc.rz(pi/2, 0)
   qc.sx(0)
   qc.rz(pi/2, 0)

   qc.cx(0, 1)

   bell_sched = schedule(qc, backend)

   with pulse.build(backend) as decoupled_bell_prep_and_measure:
       # We call our bell state preparation schedule constructed above.
       with pulse.align_right():
           pulse.call(bell_sched)
           pulse.play(pulse.Constant(bell_sched.duration, 0.02), d2)
           pulse.barrier(0, 1, 2)
           registers = pulse.measure_all()

   decoupled_bell_prep_and_measure.draw()


With the pulse builder we are able to blend programming on qubits and channels.
While the pulse schedule is based on instructions that operate on
channels, the pulse builder automatically handles the mapping from qubits to
channels for you.

In the example below we demonstrate some more features of the pulse builder:

.. code-block::

   import math
   from qiskit.compiler import schedule

   from qiskit import pulse, QuantumCircuit
   from qiskit.providers.fake_provider import FakeOpenPulse2Q

   backend = FakeOpenPulse2Q()

   qc = QuantumCircuit(2, 2)
   qc.cx(0, 1)

   with pulse.build(backend) as pulse_prog:
       # Create a pulse.
       gaussian_pulse = pulse.Gaussian(10, 1.0, 2)
       # Get the qubit's corresponding drive channel from the backend.
       d0 = pulse.drive_channel(0)
       d1 = pulse.drive_channel(1)
       # Play a pulse at t=0.
       pulse.play(gaussian_pulse, d0)
       # Play another pulse directly after the previous pulse at t=10.
       pulse.play(gaussian_pulse, d0)
       # The default scheduling behavior is to schedule pulses in parallel
       # across channels. For example, the statement below
       # plays the same pulse on a different channel at t=0.
       pulse.play(gaussian_pulse, d1)

       # We also provide pulse scheduling alignment contexts.
       # The default alignment context is align_left.

       # The sequential context schedules pulse instructions sequentially in time.
       # This context starts at t=10 due to earlier pulses above.
       with pulse.align_sequential():
           pulse.play(gaussian_pulse, d0)
           # Play another pulse after at t=20.
           pulse.play(gaussian_pulse, d1)

           # We can also nest contexts as each instruction is
           # contained in its local scheduling context.
           # The output of a child context is a context-schedule
           # with the internal instructions timing fixed relative to
           # one another. This is schedule is then called in the parent context.

           # Context starts at t=30.
           with pulse.align_left():
               # Start at t=30.
               pulse.play(gaussian_pulse, d0)
               # Start at t=30.
               pulse.play(gaussian_pulse, d1)
           # Context ends at t=40.

           # Alignment context where all pulse instructions are
           # aligned to the right, ie., as late as possible.
           with pulse.align_right():
               # Shift the phase of a pulse channel.
               pulse.shift_phase(math.pi, d1)
               # Starts at t=40.
               pulse.delay(100, d0)
               # Ends at t=140.

               # Starts at t=130.
               pulse.play(gaussian_pulse, d1)
               # Ends at t=140.

           # Acquire data for a qubit and store in a memory slot.
           pulse.acquire(100, 0, pulse.MemorySlot(0))

           # We also support a variety of macros for common operations.

           # Measure all qubits.
           pulse.measure_all()

           # Delay on some qubits.
           # This requires knowledge of which channels belong to which qubits.
           # delay for 100 cycles on qubits 0 and 1.
           pulse.delay_qubits(100, 0, 1)

           # Call a schedule for a quantum circuit thereby inserting into
           # the pulse schedule.
           qc = QuantumCircuit(2, 2)
           qc.cx(0, 1)
           qc_sched = schedule(qc, backend)
           pulse.call(qc_sched)


           # It is also be possible to call a preexisting schedule
           tmp_sched = pulse.Schedule()
           tmp_sched += pulse.Play(gaussian_pulse, d0)
           pulse.call(tmp_sched)

           # We also support:

           # frequency instructions
           pulse.set_frequency(5.0e9, d0)

           # phase instructions
           pulse.shift_phase(0.1, d0)

           # offset contexts
           with pulse.phase_offset(math.pi, d0):
               pulse.play(gaussian_pulse, d0)


The above is just a small taste of what is possible with the builder. See the rest of the module
documentation for more information on its capabilities.

.. autofunction:: build


Channels
========

Methods to return the correct channels for the respective qubit indices.

.. code-block::

    from qiskit import pulse
    from qiskit.providers.fake_provider import GenericBackendV2

    backend = GenericBackendV2(num_qubits=2, calibrate_instructions=True)

    with pulse.build(backend) as drive_sched:
        d0 = pulse.drive_channel(0)
        print(d0)

.. code-block:: text

    DriveChannel(0)

.. autofunction:: acquire_channel
.. autofunction:: control_channels
.. autofunction:: drive_channel
.. autofunction:: measure_channel


Instructions
============

Pulse instructions are available within the builder interface. Here's an example:

.. plot::
   :alt: Output from the previous code.
   :include-source:

    from qiskit import pulse
    from qiskit.providers.fake_provider import GenericBackendV2

    backend = GenericBackendV2(num_qubits=2, calibrate_instructions=True)

    with pulse.build(backend) as drive_sched:
        d0 = pulse.drive_channel(0)
        a0 = pulse.acquire_channel(0)

        pulse.play(pulse.Constant(10, 1.0), d0)
        pulse.delay(20, d0)
        pulse.shift_phase(3.14/2, d0)
        pulse.set_phase(3.14, d0)
        pulse.shift_frequency(1e7, d0)
        pulse.set_frequency(5e9, d0)

        with pulse.build() as temp_sched:
            pulse.play(pulse.Gaussian(20, 1.0, 3.0), d0)
            pulse.play(pulse.Gaussian(20, -1.0, 3.0), d0)

        pulse.call(temp_sched)
        pulse.acquire(30, a0, pulse.MemorySlot(0))

    drive_sched.draw()

.. autofunction:: acquire
.. autofunction:: barrier
.. autofunction:: call
.. autofunction:: delay
.. autofunction:: play
.. autofunction:: reference
.. autofunction:: set_frequency
.. autofunction:: set_phase
.. autofunction:: shift_frequency
.. autofunction:: shift_phase
.. autofunction:: snapshot


Contexts
========

Builder aware contexts that modify the construction of a pulse program. For
example an alignment context like :func:`align_right` may
be used to align all pulses as late as possible in a pulse program.

.. plot::
   :alt: Output from the previous code.
   :include-source:

   from qiskit import pulse

   d0 = pulse.DriveChannel(0)
   d1 = pulse.DriveChannel(1)

   with pulse.build() as pulse_prog:
       with pulse.align_right():
           # this pulse will start at t=0
           pulse.play(pulse.Constant(100, 1.0), d0)
           # this pulse will start at t=80
           pulse.play(pulse.Constant(20, 1.0), d1)

   pulse_prog.draw()

.. autofunction:: align_equispaced
.. autofunction:: align_func
.. autofunction:: align_left
.. autofunction:: align_right
.. autofunction:: align_sequential
.. autofunction:: frequency_offset
.. autofunction:: phase_offset


Macros
======

Macros help you add more complex functionality to your pulse program.

.. code-block::

    from qiskit import pulse
    from qiskit.providers.fake_provider import GenericBackendV2

    backend = GenericBackendV2(num_qubits=2, calibrate_instructions=True)

    with pulse.build(backend) as measure_sched:
        mem_slot = pulse.measure(0)
        print(mem_slot)

.. code-block:: text

    MemorySlot(0)

.. autofunction:: measure
.. autofunction:: measure_all
.. autofunction:: delay_qubits


Utilities
=========

The utility functions can be used to gather attributes about the backend and modify
how the program is built.

.. code-block::

    from qiskit import pulse

    from qiskit.providers.fake_provider import GenericBackendV2

    backend = GenericBackendV2(num_qubits=2, calibrate_instructions=True)

    with pulse.build(backend) as u3_sched:
        print('Number of qubits in backend: {}'.format(pulse.num_qubits()))

        samples = 160
        print('There are {} samples in {} seconds'.format(
            samples, pulse.samples_to_seconds(160)))

        seconds = 1e-6
        print('There are {} seconds in {} samples.'.format(
            seconds, pulse.seconds_to_samples(1e-6)))

.. code-block:: text

    Number of qubits in backend: 1
    There are 160 samples in 3.5555555555555554e-08 seconds
    There are 1e-06 seconds in 4500 samples.

.. autofunction:: active_backend
.. autofunction:: num_qubits
.. autofunction:: qubit_channels
.. autofunction:: samples_to_seconds
.. autofunction:: seconds_to_samples
é    )ÚannotationsN)Ú	GeneratorÚCallableÚIterable)Úcontextmanager)Úsingledispatchmethod)ÚTypeVarÚContextManagerÚ	TypedDictÚUnionÚOptionalÚDict)ÚParameterExpressionÚParameterValueType)ÚchannelsÚconfigurationÚ
exceptionsÚinstructionsÚmacrosÚlibraryÚ
transforms)Ú	BackendV2)Ú
directives)ÚScheduleÚScheduleBlock)ÚAlignmentKind)Údeprecate_pulse_func)é   é   )ÚUnpackÚbackendz'contextvars.ContextVar['_PulseBuilder']ÚBUILDER_CONTEXTVARÚTÚfunctionúCallable[..., T]Úreturnc                óF   ‡ — t          j        ‰ ¦  «        ˆ fd„¦   «         }|S )z\Decorator a function to raise if it is called without a builder with a
    set backend.
    c                óR   •— | j         €t          j        d¦  «        ‚ ‰| g|¢R i |¤ŽS )Nz;This function requires the builder to have a "backend" set.)r!   r   ÚBackendNotSet)ÚselfÚargsÚkwargsr$   s      €úJ/granary/edev/quantum/lib/python3.11/site-packages/qiskit/pulse/builder.pyÚwrapperz"_requires_backend.<locals>.wrapperÑ  sE   ø€ àŒ<ÐÝÔ*ØMñô ð ð ˆx˜Ð.˜tÐ.Ð.Ð. vÐ.Ð.Ð.ó    )Ú	functoolsÚwraps)r$   r.   s   ` r-   Ú_requires_backendr2   Ì  s:   ø€ õ
 „_�XÑÔð/ð /ð /ð /ñ Ôð/ð €Nr/   c                  óŒ  — e Zd ZdZ ej        ¦   «          ej        ¦   «          ej        ¦   «         dœZ	 	 	 	 d0d1d„Z	d2d„Z
d„ Zed„ ¦   «         Zd3d„Zd2d„Zd2d„Zeed„ ¦   «         ¦   «         Zd2d„Zd4d„Zd5d„Zd6d „Ze	 	 d7d8d%„¦   «         Zej        	 	 d7d9d)„¦   «         Zej        	 	 d7d:d,„¦   «         Zed;d.„¦   «         Zd/„ ZdS )<Ú_PulseBuilderzBuilder context class.)ÚleftÚrightÚ
sequentialNr5   ÚblockúScheduleBlock | NoneÚnameú
str | NoneÚdefault_alignmentústr | AlignmentKindc           	     ó²  — || _         d| _        g | _        || _        |�t	          |t
          ¦  «        r|}nMt	          |t          ¦  «        r|                      |¦  «        }n"t          j	        d|j
        j        › d�¦  «        ‚| j                             |¦  «         t	          |t          ¦  «        r|}n t          j                             ||¦  «        }t	          |t          ¦  «        sWt          j	        dt#          |¦  «        › dd                     t          j                             ¦   «         ¦  «        › d�¦  «        ‚|                      |¦  «         dS )aÊ  Initialize the builder context.

        .. note::
            At some point we may consider incorporating the builder into
            the :class:`~qiskit.pulse.Schedule` class. However, the risk of
            this is tying the user interface to the intermediate
            representation. For now we avoid this at the cost of some code
            duplication.

        Args:
            backend (Backend): Input backend to use in
                builder. If not set certain functionality will be unavailable.
            block: Initital ``ScheduleBlock`` to build on.
            name: Name of pulse program to be built.
            default_alignment: Default scheduling alignment for builder.
                One of ``left``, ``right``, ``sequential`` or an instance of
                :class:`~qiskit.pulse.transforms.alignments.AlignmentKind` subclass.

        Raises:
            PulseError: When invalid ``default_alignment`` or `block` is specified.
        NzInput `block` type z0 is not a valid format. Specify a pulse program.zGiven `default_alignment` z+ is not a valid transformation. Set one of ú, z1, or set an instance of `AlignmentKind` subclass.)Ú_backendÚ_backend_ctx_tokenÚ_context_stackÚ_nameÚ
isinstancer   r   Ú_naive_typecast_scheduler   Ú
PulseErrorÚ	__class__Ú__name__Úappendr   r4   Ú__alignment_kinds__ÚgetÚreprÚjoinÚkeysÚpush_context)r*   r!   r8   r:   r<   Ú
root_blockÚ	alignments          r-   Ú__init__z_PulseBuilder.__init__å  s†  € ð:  ˆŒð LPˆÔð 46ˆÔð ˆŒ
ð ÐÝ˜%¥Ñ/Ô/ð Ø"�
�
Ý˜E¥8Ñ,Ô,ð Ø!×:Ò:¸5ÑAÔA�
�
å Ô+ðC¨%¬/Ô*Bð Cð Cð Cñô ð ð Ô×&Ò& zÑ2Ô2Ð2õ Ð'­Ñ7Ô7ð 	dØ)ˆIˆIå%Ô9×=Ò=Ð>OÐQbÑcÔcˆIÝ˜)¥]Ñ3Ô3ð 	ÝÔ'ðB­TÐ2CÑ-DÔ-Dð Bð Bà—9’9�]Ô>×CÒCÑEÔEÑFÔFðBð Bð Bñô ð ð 	×Ò˜)Ñ$Ô$Ð$Ð$Ð$r/   r&   r   c                ó„   — t                                | ¦  «        | _        | j        d         }| j        p|j        |_        |S )zÃEnter this builder context and yield either the supplied schedule
        or the schedule created for the user.

        Returns:
            The schedule that the builder will build on.
        r   )r"   ÚsetrA   rB   rC   r:   )r*   Úoutputs     r-   Ú	__enter__z_PulseBuilder.__enter__(  s<   € õ #5×"8Ò"8¸Ñ">Ô">ˆÔØÔ$ QÔ'ˆØ”zÐ0 V¤[ˆŒàˆr/   c                ól   — |                       ¦   «          t                               | j        ¦  «         dS )z=Exit the builder context and compile the built pulse program.N)Úcompiler"   ÚresetrA   )r*   Úexc_typeÚexc_valÚexc_tbs       r-   Ú__exit__z_PulseBuilder.__exit__5  s,   € à�Š‰ŒˆÝ× Ò  Ô!8Ñ9Ô9Ð9Ð9Ð9r/   c                ó   — | j         S )ztReturns the builder backend if set.

        Returns:
            Optional[Backend]: The builder's backend.
        )r@   ©r*   s    r-   r!   z_PulseBuilder.backend:  s   € ð Œ}Ðr/   rQ   r   c                óV   — | j                              t          |¬¦  «        ¦  «         dS )zPush new context to the stack.)Úalignment_contextN)rB   rI   r   )r*   rQ   s     r-   rO   z_PulseBuilder.push_contextC  s*   € àÔ×"Ò"¥=À9Ð#MÑ#MÔ#MÑNÔNÐNÐNÐNr/   c                óŒ   — t          | j        ¦  «        dk    rt          j        d¦  «        ‚| j                             ¦   «         S )z$Pop the last context from the stack.é   z&The root context cannot be popped out.)ÚlenrB   r   rF   Úpopr_   s    r-   Úpop_contextz_PulseBuilder.pop_contextG  s?   € åˆtÔ"Ñ#Ô# qÒ(Ð(ÝÔ'Ð(PÑQÔQÐQàÔ"×&Ò&Ñ(Ô(Ð(r/   c                ó   — | j         d         S )zäGet current context.

        Notes:
            New instruction can be added by `.append_subroutine` or `.append_instruction` method.
            Use above methods rather than directly accessing to the current context.
        éÿÿÿÿ)rB   r_   s    r-   Úget_contextz_PulseBuilder.get_contextN  s   € ð Ô" 2Ô&Ð&r/   c                óŠ   — t          | j        t          ¦  «        r| j        j        S | j                             ¦   «         j        S )z(Get the number of qubits in the backend.)rD   r!   r   Ú
num_qubitsr   Ún_qubitsr_   s    r-   rk   z_PulseBuilder.num_qubitsW  s:   € õ
 �d”l¥IÑ.Ô.ð 	+Ø”<Ô*Ð*ØŒ|×)Ò)Ñ+Ô+Ô4Ð4r/   c                óÎ   — t          | j        ¦  «        dk    rA|                      ¦   «         }|                      |¦  «         t          | j        ¦  «        dk    °A| j        d         S )z+Compile and output the built pulse program.rc   r   )rd   rB   rf   Úappend_subroutine)r*   Úcurrents     r-   rX   z_PulseBuilder.compile`  sg   € õ �$Ô%Ñ&Ô&¨Ò*Ð*Ø×&Ò&Ñ(Ô(ˆGØ×"Ò" 7Ñ+Ô+Ð+õ �$Ô%Ñ&Ô&¨Ò*Ð*ð Ô" 1Ô%Ð%r/   Úinstructionúinstructions.Instructionc                óF   — | j         d                              |¦  «         dS )z}Add an instruction to the builder's context schedule.

        Args:
            instruction: Instruction to append.
        rh   N)rB   rI   )r*   rp   s     r-   Úappend_instructionz _PulseBuilder.append_instructionl  s&   € ð 	Ô˜BÔ×&Ò& {Ñ3Ô3Ð3Ð3Ð3r/   ÚstrÚ
extra_keysc                óT   — t          j        |g|¢R Ž }|                      |¦  «         dS )zÞAdd external program as a :class:`~qiskit.pulse.instructions.Reference` instruction.

        Args:
            name: Name of subroutine.
            extra_keys: Assistance keys to uniquely specify the subroutine.
        N)r   Ú	Referencers   )r*   r:   ru   Úinsts       r-   Úappend_referencez_PulseBuilder.append_referencet  s6   € õ Ô% dÐ8¨ZÐ8Ð8Ð8ˆØ×Ò Ñ%Ô%Ð%Ð%Ð%r/   Ú
subroutineúSchedule | ScheduleBlockc                ó@  — t          |t          t          f¦  «        s"t          j        d|j        j        › d�¦  «        ‚t          |¦  «        dk    rdS t          |t          ¦  «        r|                      |¦  «        }| j	        d          
                    |¦  «         dS )a}  Append a :class:`ScheduleBlock` to the builder's context schedule.

        This operation doesn't create a reference. Subroutine is directly
        appended to current context schedule.

        Args:
            subroutine: ScheduleBlock to append to the current context block.

        Raises:
            PulseError: When subroutine is not Schedule nor ScheduleBlock.
        ú'zq' is not valid data format in the builder. 'Schedule' and 'ScheduleBlock' can be appended to the builder context.r   Nrh   )rD   r   r   r   rF   rG   rH   rd   rE   rB   rI   )r*   rz   s     r-   rn   z_PulseBuilder.append_subroutine~  s°   € õ ˜*¥}µhÐ&?Ñ@Ô@ð 	ÝÔ'ðY�JÔ(Ô1ð Yð Yð Yñô ð õ
 ˆz‰?Œ?˜aÒÐØˆFÝ�j¥(Ñ+Ô+ð 	CØ×6Ò6°zÑBÔBˆJØÔ˜BÔ×&Ò& zÑ2Ô2Ð2Ð2Ð2r/   Ú
value_dictú4dict[ParameterExpression, ParameterValueType] | NoneÚ	kw_paramsr   c                óF   — t          j        d|j        j        › d�¦  «        ‚)ax  Call a schedule or circuit defined outside of the current scope.

        The ``subroutine`` is appended to the context schedule as a call instruction.
        This logic just generates a convenient program representation in the compiler.
        Thus, this doesn't affect execution of inline subroutines.
        See :class:`~pulse.instructions.Call` for more details.

        Args:
            subroutine: Target schedule or circuit to append to the current context.
            name: Name of subroutine if defined.
            value_dict: Parameter object and assigned value mapping. This is more precise way to
                identify a parameter since mapping is managed with unique object id rather than
                name. Especially there is any name collision in a parameter table.
            kw_params: Parameter values to bind to the target subroutine
                with string parameter names. If there are parameter name overlapping,
                these parameters are updated with the same assigned value.

        Raises:
            PulseError:
                - When input subroutine is not valid data format.
        zSubroutine type z; is not valid data format. Call Schedule, or ScheduleBlock.)r   rF   rG   rH   )r*   rz   r:   r~   r€   s        r-   Úcall_subroutinez_PulseBuilder.call_subroutine–  s5   € õ: Ô#ð*˜zÔ3Ô<ð *ð *ð *ñ
ô 
ð 	
r/   Útarget_blockúOptional[str]ú7Optional[Dict[ParameterExpression, ParameterValueType]]c                óÐ  — t          |¦  «        dk    rd S i }|                     ¦   «         D ]l\  }}|                     |¦  «        }|sFt          j        d|› dd                     t          t          |j        ¦  «        ¦  «        › d�¦  «        ‚|D ]}	|||	<   ŒŒm|rX| 	                    ¦   «         | 	                    ¦   «         z  rt          j        dt          ¦  «         |                     |¦  «         |r|                     |d¬¦  «        }|€ |j        t!          j        ¦   «         j        f}
n|f}
 | j        |
Ž  |                      ¦   «                              |
|id	¬¦  «         d S )
Nr   z
Parameter z* is not defined in the target subroutine. r?   z can be specified.z¨Some parameters provided by 'value_dict' conflict with one through keyword arguments. Parameter values in the keyword arguments are overridden by the dictionary values.F©ÚinplaceT)rd   ÚitemsÚget_parametersr   rF   rM   Úmaprt   Ú
parametersrN   ÚwarningsÚwarnÚUserWarningÚupdateÚassign_parametersr:   ÚuuidÚuuid4Úhexry   ri   Úassign_references)r*   rƒ   r:   r~   r€   Úlocal_assignmentÚ
param_nameÚvalueÚparamsÚparamrN   s              r-   Ú_z_PulseBuilder._¹  sÀ  € õ ˆ|ÑÔ Ò!Ð!ØˆFð ÐØ!*§¢Ñ!2Ô!2ð 	0ð 	0ÑˆJ˜Ø!×0Ò0°Ñ<Ô<ˆFØð Ý Ô+ðX ð Xð XØ—y’y¥¥S¨,Ô*AÑ!BÔ!BÑCÔCðXð Xð Xñô ð ð  ð 0ð 0�Ø*/Ð  Ñ'Ð'ð0ð ð 	0Ø×$Ò$Ñ&Ô&¨¯ªÑ):Ô):Ñ:ð Ý”ð?õ  ñ	ô ð ð ×#Ò# JÑ/Ô/Ð/àð 	[Ø'×9Ò9Ð:JÐTYÐ9ÑZÔZˆLàˆ<à%1Ô%6½¼
¹¼Ô8HÐ$IˆDˆDà�7ˆDàˆÔ˜tÐ$Ð$Ø×ÒÑÔ×,Ò,¨d°LÐ-AÈ4Ð,ÑPÔPÐPÐPÐPr/   Útarget_scheduler   c                óx   — t          |¦  «        dk    rd S  | j        |                      |¦  «        f||dœ|¤Ž d S )Nr   )r:   r~   )rd   r‚   rE   )r*   rœ   r:   r~   r€   s        r-   r›   z_PulseBuilder._æ  sh   € õ ˆÑÔ 1Ò$Ð$ØˆFàˆÔØ×)Ò)¨/Ñ:Ô:ð	
àØ!ð	
ð 	
ð ð		
ð 	
ð 	
ð 	
ð 	
r/   Úschedulec                óä   — ddl m}m}m}  | || ¦  «        ¦  «        } ||dt          j        ¬¦  «         t          | j        ¬¦  «        }|j        D ]\  }}|                     |d¬¦  «         Œ|S )Nr   )Úinline_subroutinesÚflattenÚpadT)rˆ   Úpad_with©r:   r‡   )	Úqiskit.pulse.transformsr    r¡   r¢   r   ÚTimeBlockader   r:   rI   )rž   r    r¡   r¢   Úpreprocessed_schedulerƒ   r›   rx   s           r-   rE   z&_PulseBuilder._naive_typecast_scheduleø  s¥   € ð 	MÐLÐLÐLÐLÐLÐLÐLÐLÐLà 2Ð 2°7°7¸8Ñ3DÔ3DÑ EÔ EÐØˆÐ!¨4½,Ô:SÐTÑTÔTÐTõ %¨(¬-Ð8Ñ8Ô8ˆØ,Ô9ð 	4ð 	4‰GˆAˆtØ×Ò ¨dÐÑ3Ô3Ð3Ð3àÐr/   c                óŠ   — t          | j        t          ¦  «        r| j        j        S | j                             ¦   «         j        S )z4Retrieve dt differently based on the type of Backend)rD   r!   r   Údtr   r_   s    r-   Úget_dtz_PulseBuilder.get_dt  s7   € å�d”l¥IÑ.Ô.ð 	#Ø”<”?Ð"ØŒ|×)Ò)Ñ+Ô+Ô.Ð.r/   ©NNNr5   )r8   r9   r:   r;   r<   r=   )r&   r   )rQ   r   ©rp   rq   ©r:   rt   ru   rt   )rz   r{   ©NN)rz   r{   r:   r;   r~   r   r€   r   )rƒ   r   r:   r„   r~   r…   r€   r   )rœ   r   r:   r„   r~   r…   r€   r   )rž   r   )rH   Ú
__module__Ú__qualname__Ú__doc__r   Ú	AlignLeftÚ
AlignRightÚAlignSequentialrJ   rR   rV   r]   Úpropertyr!   rO   rf   ri   r2   rk   rX   rs   ry   rn   r   r‚   Úregisterr›   ÚstaticmethodrE   rª   © r/   r-   r4   r4   Ü  s:  € € € € € Ø Ð ð %�
Ô$Ñ&Ô&Ø&�Ô&Ñ(Ô(Ø0�jÔ0Ñ2Ô2ðð Ðð Ø&*ØØ17ðA%ð A%ð A%ð A%ð A%ðFð ð ð ð:ð :ð :ð
 ðð ñ „XððOð Oð Oð Oð)ð )ð )ð )ð'ð 'ð 'ð 'ð Øð5ð 5ñ Ôñ „Xð5ð
&ð 
&ð 
&ð 
&ð4ð 4ð 4ð 4ð&ð &ð &ð &ð3ð 3ð 3ð 3ð0 ð  ØKOð	 
ð  
ð  
ð  
ñ Ôð 
ðD Ôð #ØNRð	*Qð *Qð *Qð *Qñ Ôð*QðX Ôð #ØNRð	
ð 
ð 
ð 
ñ Ôð
ð" ðð ð ñ „\ðð/ð /ð /ð /ð /r/   r4   r5   rž   r9   r:   r;   r<   ústr | AlignmentKind | NoneúContextManager[ScheduleBlock]c                ó(   — t          | |||¬¦  «        S )a¼  Create a context manager for launching the imperative pulse builder DSL.

    To enter a building context and starting building a pulse program:

    .. code-block::

        from qiskit import transpile, pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.play(pulse.Constant(100, 0.5), d0)


    While the output program ``pulse_prog`` cannot be executed as we are using
    a mock backend. If a real backend is being used, executing the program is
    done with:

    .. code-block:: python

        backend.run(transpile(pulse_prog, backend))

    Args:
        backend (Backend): A Qiskit backend. If not supplied certain
            builder functionality will be unavailable.
        schedule: A pulse ``ScheduleBlock`` in which your pulse program will be built.
        name: Name of pulse program to be built.
        default_alignment: Default scheduling alignment for builder.
            One of ``left``, ``right``, ``sequential`` or an alignment context.

    Returns:
        A new builder context which has the active builder initialized.
    )r!   r8   r:   r<   )r4   )r!   rž   r:   r<   s       r-   Úbuildr¼     s(   € õV ØØØØ+ð	ñ ô ð r/   c                 ó„   — 	 t                                ¦   «         S # t          $ r} t          j        d¦  «        | ‚d} ~ ww xY w)zðGet the active builder in the active context.

    Returns:
        The active active builder in this context.

    Raises:
        exceptions.NoActiveBuilder: If a pulse builder function is called
        outside of a builder context.
    z“A Pulse builder function was called outside of a builder context. Try calling within a builder context, eg., "with pulse.build() as schedule: ...".N)r"   rK   ÚLookupErrorr   ÚNoActiveBuilder)Úexs    r-   Ú_active_builderrÁ   D  sX   € ðÝ!×%Ò%Ñ'Ô'Ð'øÝð ð ð ÝÔ(ðCñ
ô 
ð ð		øøøøðøøøs   ‚ ›
?¥:º?c                 óX   — t          ¦   «         j        } | €t          j        d¦  «        ‚| S )zÿGet the backend of the currently active builder context.

    Returns:
        Backend: The active backend in the currently active
            builder context.

    Raises:
        exceptions.BackendNotSet: If the builder does not have a backend set.
    NzBThis function requires the active builder to have a "backend" set.)rÁ   r!   r   r)   )Úbuilders    r-   Úactive_backendrÄ   X  s6   € õ ÑÔÔ'€GØ€ÝÔ&ØPñ
ô 
ð 	
ð €Nr/   r{   c                óH   — t          ¦   «                              | ¦  «         dS )zŠCall a schedule by appending to the active builder's context block.

    Args:
        schedule: Schedule or ScheduleBlock to append.
    N)rÁ   rn   )rž   s    r-   Úappend_schedulerÆ   k  s$   € õ ÑÔ×'Ò'¨Ñ1Ô1Ð1Ð1Ð1r/   rp   rq   c                óH   — t          ¦   «                              | ¦  «         dS )a‰  Append an instruction to the active builder's context schedule.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.builder.append_instruction(pulse.Delay(10, d0))

        print(pulse_prog.instructions)

    .. code-block:: text

        ((0, Delay(10, DriveChannel(0))),)
    N)rÁ   rs   )rp   s    r-   rs   rs   t  s$   € õ( ÑÔ×(Ò(¨Ñ5Ô5Ð5Ð5Ð5r/   Úintc                 ó´   — t          t          ¦   «         t          ¦  «        rt          ¦   «         j        S t          ¦   «                              ¦   «         j        S )a£  Return number of qubits in the currently active backend.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend):
            print(pulse.num_qubits())

    .. code-block:: text

       2

    .. note:: Requires the active builder context to have a backend set.
    )rD   rÄ   r   rk   r   rl   r¸   r/   r-   rk   rk   ‹  sF   € õ, •.Ñ"Ô"¥IÑ.Ô.ð +ÝÑÔÔ*Ð*ÝÑÔ×)Ò)Ñ+Ô+Ô4Ð4r/   Úsecondsúfloat | np.ndarrayúint | np.ndarrayc                óÔ   — t          ¦   «                              ¦   «         }t          | t          j        ¦  «        r| |z                       t          ¦  «        S t          | |z  ¦  «        S )zôObtain the number of samples that will elapse in ``seconds`` on the
    active backend.

    Rounds down.

    Args:
        seconds: Time in seconds to convert to samples.

    Returns:
        The number of samples for the time to elapse
    )rÁ   rª   rD   ÚnpÚndarrayÚastyperÈ   )rÊ   r©   s     r-   Úseconds_to_samplesrÑ   ¦  sY   € õ 
Ñ	Ô	×	!Ò	!Ñ	#Ô	#€BÝ�'�2œ:Ñ&Ô&ð *Ø˜"‘×$Ò$¥SÑ)Ô)Ð)Ýˆw˜‰|ÑÔÐr/   Úsamplesc                óH   — | t          ¦   «                              ¦   «         z  S )zôObtain the time in seconds that will elapse for the input number of
    samples on the active backend.

    Args:
        samples: Number of samples to convert to time in seconds.

    Returns:
        The time that elapses in ``samples``.
    )rÁ   rª   )rÒ   s    r-   Úsamples_to_secondsrÔ   ¹  s!   € ð •_Ñ&Ô&×-Ò-Ñ/Ô/Ñ/Ð/r/   Úqubitúset[chans.Channel]c                ó  — dd„}t          t          ¦   «         t          ¦  «        r%t           |t          ¦   «         | ¦  «        ¦  «        S t          t          ¦   «                              ¦   «                              | ¦  «        ¦  «        S )a’  Returns the set of channels associated with a qubit.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend):
            print(pulse.qubit_channels(0))

    .. code-block:: text

       {MeasureChannel(0), ControlChannel(0), DriveChannel(0), AcquireChannel(0), ControlChannel(1)}

    .. note:: Requires the active builder context to have a backend set.

    .. note:: A channel may still be associated with another qubit in this list
        such as in the case where significant crosstalk exists.

    r!   r   rÕ   rÈ   c                ón  — g }| j         D ]2}||v r,|                      |¦  «        }|r|                     |¦  «         Œ3|                     |                      |¦  «        ¦  «         |                     |                      |¦  «        ¦  «         |                     |                      |¦  «        ¦  «         |S )zŸReturn a list of channels which operate on the given ``qubit``.
        Returns:
            List of ``Channel``\s operated on my the given ``qubit``.
        )Úcoupling_mapÚcontrol_channelÚextendrI   Údrive_channelÚmeasure_channelÚacquire_channel)r!   rÕ   r   Únode_qubitsrÚ   s        r-   Úget_qubit_channels_v2z-qubit_channels.<locals>.get_qubit_channels_v2ã  s½   € ð
 ˆð #Ô/ð 	5ð 	5ˆKØ˜Ð#Ð#Ø")×"9Ò"9¸+Ñ"FÔ"F�Ø"ð 5Ø—O’O OÑ4Ô4Ð4øð 	�Š˜×-Ò-¨eÑ4Ô4Ñ5Ô5Ð5Ø�Š˜×/Ò/°Ñ6Ô6Ñ7Ô7Ð7Ø�Š˜×/Ò/°Ñ6Ô6Ñ7Ô7Ð7Øˆr/   )r!   r   rÕ   rÈ   )rD   rÄ   r   rT   r   Úget_qubit_channels)rÕ   rà   s     r-   Úqubit_channelsrâ   Ç  s�   € ð8ð ð ð õ* •.Ñ"Ô"¥IÑ.Ô.ð CÝÐ(Ð(­Ñ)9Ô)9¸5ÑAÔAÑBÔBÐBÝ�~ÑÔ×-Ò-Ñ/Ô/×BÒBÀ5ÑIÔIÑJÔJÐJr/   Úchannels_or_qubitsúint | chans.Channelc                 ó  — t          ¦   «         }| D ]p}t          |t          ¦  «        r|t          |¦  «        z  }Œ*t          |t          j        ¦  «        r|                     |¦  «         ŒZt          j        |› d�¦  «        ‚|S )z0Returns the unique channels of the input qubits.z' is not a "Channel" or qubit (integer).)	rT   rD   rÈ   râ   ÚchansÚChannelÚaddr   rF   )rã   r   Úchannel_or_qubits      r-   Ú_qubits_to_channelsrê   ý  s–   € å‰uŒu€HØ.ð ð ÐÝÐ&­Ñ,Ô,ð 	Ø�Ð'7Ñ8Ô8Ñ8ˆHˆHÝÐ(­%¬-Ñ8Ô8ð 	Ø�LŠLÐ)Ñ*Ô*Ð*Ð*åÔ'Ø#ÐLÐLÐLñô ð ð €Or/   úGenerator[None, None, None]c               #  ó*  K  — t          ¦   «         } |                      t          j        ¦   «         ¦  «         	 dV — |                      ¦   «         }|                      |¦  «         dS # |                      ¦   «         }|                      |¦  «         w xY w)a  Left alignment pulse scheduling context.

    Pulse instructions within this context are scheduled as early as possible
    by shifting them left to the earliest available time.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)

        with pulse.build() as pulse_prog:
            with pulse.align_left():
                # this pulse will start at t=0
                pulse.play(pulse.Constant(100, 1.0), d0)
                # this pulse will start at t=0
                pulse.play(pulse.Constant(20, 1.0), d1)
        pulse_prog = pulse.transforms.block_to_schedule(pulse_prog)

        assert pulse_prog.ch_start_time(d0) == pulse_prog.ch_start_time(d1)

    Yields:
        None
    N)rÁ   rO   r   r²   rf   rn   ©rÃ   ro   s     r-   Ú
align_leftrî     s—   è è € õ< ÑÔ€GØ×Ò�Ô-Ñ/Ô/Ñ0Ô0Ð0ð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøøó   ¸A' Á'+Bc               #  ó*  K  — t          ¦   «         } |                      t          j        ¦   «         ¦  «         	 dV — |                      ¦   «         }|                      |¦  «         dS # |                      ¦   «         }|                      |¦  «         w xY w)a  Right alignment pulse scheduling context.

    Pulse instructions within this context are scheduled as late as possible
    by shifting them right to the latest available time.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)

        with pulse.build() as pulse_prog:
            with pulse.align_right():
                # this pulse will start at t=0
                pulse.play(pulse.Constant(100, 1.0), d0)
                # this pulse will start at t=80
                pulse.play(pulse.Constant(20, 1.0), d1)
        pulse_prog = pulse.transforms.block_to_schedule(pulse_prog)

        assert pulse_prog.ch_stop_time(d0) == pulse_prog.ch_stop_time(d1)

    Yields:
        None
    N)rÁ   rO   r   r³   rf   rn   rí   s     r-   Úalign_rightrñ   6  s—   è è € õ< ÑÔ€GØ×Ò�Ô.Ñ0Ô0Ñ1Ô1Ð1ð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøørï   c               #  ó*  K  — t          ¦   «         } |                      t          j        ¦   «         ¦  «         	 dV — |                      ¦   «         }|                      |¦  «         dS # |                      ¦   «         }|                      |¦  «         w xY w)a(  Sequential alignment pulse scheduling context.

    Pulse instructions within this context are scheduled sequentially in time
    such that no two instructions will be played at the same time.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)

        with pulse.build() as pulse_prog:
            with pulse.align_sequential():
                # this pulse will start at t=0
                pulse.play(pulse.Constant(100, 1.0), d0)
                # this pulse will also start at t=100
                pulse.play(pulse.Constant(20, 1.0), d1)
        pulse_prog = pulse.transforms.block_to_schedule(pulse_prog)

        assert pulse_prog.ch_stop_time(d0) == pulse_prog.ch_start_time(d1)

    Yields:
        None
    N)rÁ   rO   r   r´   rf   rn   rí   s     r-   Úalign_sequentialró   ]  s—   è è € õ< ÑÔ€GØ×Ò�Ô3Ñ5Ô5Ñ6Ô6Ð6ð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøørï   Údurationúint | ParameterExpressionc              #  ó.  K  — t          ¦   «         }|                     t          j        | ¬¦  «        ¦  «         	 dV — |                     ¦   «         }|                     |¦  «         dS # |                     ¦   «         }|                     |¦  «         w xY w)a¥  Equispaced alignment pulse scheduling context.

    Pulse instructions within this context are scheduled with the same interval spacing such that
    the total length of the context block is ``duration``.
    If the total free ``duration`` cannot be evenly divided by the number of instructions
    within the context, the modulo is split and then prepended and appended to
    the returned schedule. Delay instructions are automatically inserted in between pulses.

    This context is convenient to write a schedule for periodical dynamic decoupling or
    the Hahn echo sequence.

    Examples:

    .. plot::
       :alt: Output from the previous code.
       :include-source:

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)
        x90 = pulse.Gaussian(10, 0.1, 3)
        x180 = pulse.Gaussian(10, 0.2, 3)

        with pulse.build() as hahn_echo:
            with pulse.align_equispaced(duration=100):
                pulse.play(x90, d0)
                pulse.play(x180, d0)
                pulse.play(x90, d0)

        hahn_echo.draw()

    Args:
        duration: Duration of this context. This should be larger than the schedule duration.

    Yields:
        None

    Notes:
        The scheduling is performed for sub-schedules within the context rather than
        channel-wise. If you want to apply the equispaced context for each channel,
        you should use the context independently for channels.
    )rô   N)rÁ   rO   r   ÚAlignEquispacedrf   rn   )rô   rÃ   ro   s      r-   Úalign_equispacedrø   „  s�   è è € õZ ÑÔ€GØ×Ò�Ô3¸XÐFÑFÔFÑGÔGÐGð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøøs   ºA) Á)+BÚfuncúCallable[[int], float]c              #  ó0  K  — t          ¦   «         }|                     t          j        | |¬¦  «        ¦  «         	 dV — |                     ¦   «         }|                     |¦  «         dS # |                     ¦   «         }|                     |¦  «         w xY w)a¿  Callback defined alignment pulse scheduling context.

    Pulse instructions within this context are scheduled at the location specified by
    arbitrary callback function `position` that takes integer index and returns
    the associated fractional location within [0, 1].
    Delay instruction is automatically inserted in between pulses.

    This context may be convenient to write a schedule of arbitrary dynamical decoupling
    sequences such as Uhrig dynamical decoupling.

    Examples:

    .. plot::
       :alt: Output from the previous code.
       :include-source:

        import numpy as np
        from qiskit import pulse

        d0 = pulse.DriveChannel(0)
        x90 = pulse.Gaussian(10, 0.1, 3)
        x180 = pulse.Gaussian(10, 0.2, 3)

        def udd10_pos(j):
            return np.sin(np.pi*j/(2*10 + 2))**2

        with pulse.build() as udd_sched:
            pulse.play(x90, d0)
            with pulse.align_func(duration=300, func=udd10_pos):
                for _ in range(10):
                    pulse.play(x180, d0)
            pulse.play(x90, d0)

        udd_sched.draw()

    Args:
        duration: Duration of context. This should be larger than the schedule duration.
        func: A function that takes an index of sub-schedule and returns the
            fractional coordinate of of that sub-schedule.
            The returned value should be defined within [0, 1].
            The pulse index starts from 1.

    Yields:
        None

    Notes:
        The scheduling is performed for sub-schedules within the context rather than
        channel-wise. If you want to apply the numerical context for each channel,
        you need to apply the context independently to channels.
    )rô   rù   N)rÁ   rO   r   Ú	AlignFuncrf   rn   )rô   rù   rÃ   ro   s       r-   Ú
align_funcrý   º  sŸ   è è € õn ÑÔ€GØ×Ò�Ô-°xÀdÐKÑKÔKÑLÔLÐLð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøøs   »A* Á*+Bra   r   c              #  óZ  K  — t          | t          ¦  «        st          j        d¦  «        ‚t	          ¦   «         }|                     | ¦  «         	 dV — |                     ¦   «         }|                     |¦  «         dS # |                     ¦   «         }|                     |¦  «         w xY w)aq  Arbitrary alignment transformation defined by a subclass instance of
    :class:`~qiskit.pulse.transforms.alignments.AlignmentKind`.

    Args:
        alignment_context: Alignment context instance that defines schedule transformation.

    Yields:
        None

    Raises:
        PulseError: When input ``alignment_context`` is not ``AlignmentKind`` subclasses.
    z8Input alignment context is not `AlignmentKind` subclass.N)rD   r   r   rF   rÁ   rO   rf   rn   )ra   rÃ   ro   s      r-   Úgeneral_transformsrÿ   ú  sµ   è è € õ Ð'­Ñ7Ô7ð `ÝÔ#Ð$^Ñ_Ô_Ð_åÑÔ€GØ×ÒÐ*Ñ+Ô+Ð+ð+Øˆˆˆà×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*øð ×%Ò%Ñ'Ô'ˆØ×!Ò! 'Ñ*Ô*Ð*Ð*øøøs   ÁA? Á?+B*ÚphaseÚfloatr   úchans.PulseChannelc              '  ó    K  — |D ]}t          | |¦  «         Œ	 dV — |D ]}t          |  |¦  «         ŒdS # |D ]}t          |  |¦  «         Œw xY w)a  Shift the phase of input channels on entry into context and undo on exit.

    Examples:

    .. code-block::

        import math

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            with pulse.phase_offset(math.pi, d0):
                pulse.play(pulse.Constant(10, 1.0), d0)

        assert len(pulse_prog.instructions) == 3

    Args:
        phase: Amount of phase offset in radians.
        channels: Channels to offset phase of.

    Yields:
        None
    N)Úshift_phase)r   r   Úchannels      r-   Úphase_offsetr    s’   è è € ð8 ð $ð $ˆÝ�E˜7Ñ#Ô#Ð#Ð#ð)Øˆˆˆàð 	)ð 	)ˆGÝ˜˜ Ñ(Ô(Ð(Ð(ð	)ð 	)ø�xð 	)ð 	)ˆGÝ˜˜ Ñ(Ô(Ð(Ð(ð	)øøøs	   ™5 µAF)Úcompensate_phaseÚ	frequencyr  Úboolc             '  ór  K  — t          ¦   «         }|                     ¦   «         j        }|D ]}t          | |¦  «         Œ	 dV — |r_|                     ¦   «         j        |z
  }dt          j        z  ||                     ¦   «         z  | z  dz  z  }|D ]}t          | |¦  «         Œ|D ]}t          |  |¦  «         ŒdS # |r_|                     ¦   «         j        |z
  }dt          j        z  ||                     ¦   «         z  | z  dz  z  }|D ]}t          | |¦  «         Œ|D ]}t          |  |¦  «         Œw xY w)aÕ  Shift the frequency of inputs channels on entry into context and undo on exit.

    Examples:

    .. code-block:: python
        :emphasize-lines: 7, 16

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()
        d0 = pulse.DriveChannel(0)

        with pulse.build(backend) as pulse_prog:
            # shift frequency by 1GHz
            with pulse.frequency_offset(1e9, d0):
                pulse.play(pulse.Constant(10, 1.0), d0)

        assert len(pulse_prog.instructions) == 3

        with pulse.build(backend) as pulse_prog:
            # Shift frequency by 1GHz.
            # Undo accumulated phase in the shifted frequency frame
            # when exiting the context.
            with pulse.frequency_offset(1e9, d0, compensate_phase=True):
                pulse.play(pulse.Constant(10, 1.0), d0)

        assert len(pulse_prog.instructions) == 4

    Args:
        frequency: Amount of frequency offset in Hz.
        channels: Channels to offset frequency of.
        compensate_phase: Compensate for accumulated phase accumulated with
            respect to the channels' frame at its initial frequency.

    Yields:
        None
    Né   rc   )rÁ   ri   rô   Úshift_frequencyrÎ   Úpirª   r  )r  r  r   rÃ   Út0r  rô   Úaccumulated_phases           r-   Úfrequency_offsetr  9  s›  è è € õV ÑÔ€Gð
 
×	Ò	Ñ	Ô	Ô	'€Bàð ,ð ,ˆÝ˜	 7Ñ+Ô+Ð+Ð+ð1Øˆˆˆàð 	9Ø×*Ò*Ñ,Ô,Ô5¸Ñ:ˆHà !¥B¤E¡	¨h¸¿ºÑ9IÔ9IÑ.IÈIÑ.UÐYZÑ-ZÑ [ÐØ#ð 9ð 9�ÝÐ.Ð.°Ñ8Ô8Ð8Ð8àð 	1ð 	1ˆGÝ˜Y˜J¨Ñ0Ô0Ð0Ð0ð	1ð 	1øð ð 	9Ø×*Ò*Ñ,Ô,Ô5¸Ñ:ˆHà !¥B¤E¡	¨h¸¿ºÑ9IÔ9IÑ.IÈIÑ.UÐYZÑ-ZÑ [ÐØ#ð 9ð 9�ÝÐ.Ð.°Ñ8Ô8Ð8Ð8àð 	1ð 	1ˆGÝ˜Y˜J¨Ñ0Ô0Ð0Ð0ð	1øøøs   Á B= Â=A9D6úchans.DriveChannelc                óì   — t          t          ¦   «         t          ¦  «        r!t          ¦   «                              | ¦  «        S t          ¦   «                              ¦   «                              | ¦  «        S )a¨  Return ``DriveChannel`` for ``qubit`` on the active builder backend.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend):
            assert pulse.drive_channel(0) == pulse.DriveChannel(0)

    .. note:: Requires the active builder context to have a backend set.
    )rD   rÄ   r   rÜ   r   Údrive©rÕ   s    r-   rÜ   rÜ   |  s\   € õ& •.Ñ"Ô"¥IÑ.Ô.ð 5ÝÑÔ×-Ò-¨eÑ4Ô4Ð4ÝÑÔ×)Ò)Ñ+Ô+×1Ò1°%Ñ8Ô8Ð8r/   úchans.MeasureChannelc                óì   — t          t          ¦   «         t          ¦  «        r!t          ¦   «                              | ¦  «        S t          ¦   «                              ¦   «                              | ¦  «        S )a®  Return ``MeasureChannel`` for ``qubit`` on the active builder backend.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend):
            assert pulse.measure_channel(0) == pulse.MeasureChannel(0)

    .. note:: Requires the active builder context to have a backend set.
    )rD   rÄ   r   rÝ   r   Úmeasurer  s    r-   rÝ   rÝ   ”  ó\   € õ& •.Ñ"Ô"¥IÑ.Ô.ð 7ÝÑÔ×/Ò/°Ñ6Ô6Ð6ÝÑÔ×)Ò)Ñ+Ô+×3Ò3°EÑ:Ô:Ð:r/   úchans.AcquireChannelc                óì   — t          t          ¦   «         t          ¦  «        r!t          ¦   «                              | ¦  «        S t          ¦   «                              ¦   «                              | ¦  «        S )a®  Return ``AcquireChannel`` for ``qubit`` on the active builder backend.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend):
            assert pulse.acquire_channel(0) == pulse.AcquireChannel(0)

    .. note:: Requires the active builder context to have a backend set.
    )rD   rÄ   r   rÞ   r   Úacquirer  s    r-   rÞ   rÞ   ¬  r  r/   ÚqubitsúIterable[int]úlist[chans.ControlChannel]c                 óî   — t          t          ¦   «         t          ¦  «        r!t          ¦   «                              | ¦  «        S t          ¦   «                              ¦   «                              | ¬¦  «        S )a  Return ``ControlChannel`` for ``qubit`` on the active builder backend.

    Return the secondary drive channel for the given qubit -- typically
    utilized for controlling multi-qubit interactions.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()
        with pulse.build(backend):
            assert pulse.control_channels(0, 1) == [pulse.ControlChannel(0)]

    .. note:: Requires the active builder context to have a backend set.

    Args:
      qubits: Tuple or list of ordered qubits of the form
        `(control_qubit, target_qubit)`.

    Returns:
        List of control channels associated with the supplied ordered list
        of qubits.
    ©r  )rD   rÄ   r   rÚ   r   Úcontrolr   s    r-   Úcontrol_channelsr"  Ä  s_   € õ: •.Ñ"Ô"¥IÑ.Ô.ð 8ÝÑÔ×/Ò/°Ñ7Ô7Ð7ÝÑÔ×)Ò)Ñ+Ô+×3Ò3¸6Ð3ÑBÔBÐBr/   r  úchans.Channelc                óN   — t          t          j        | ||¬¦  «        ¦  «         dS )a|  Delay on a ``channel`` for a ``duration``.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.delay(10, d0)

    Args:
        duration: Number of cycles to delay for on ``channel``.
        channel: Channel to delay on.
        name: Name of the instruction.
    r¤   N)rs   r   ÚDelay)rô   r  r:   s      r-   Údelayr&  ç  s*   € õ( •|Ô)¨(°GÀ$ÐGÑGÔGÑHÔHÐHÐHÐHr/   Úpulseúlibrary.Pulse | np.ndarrayc                óª   — t          | t          j        ¦  «        st          j        | ¦  «        } t	          t          j        | ||¬¦  «        ¦  «         dS )ae  Play a ``pulse`` on a ``channel``.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.play(pulse.Constant(10, 1.0), d0)

    Args:
        pulse: Pulse to play.
        channel: Channel to play pulse on.
        name: Name of the pulse.
    r¤   N)rD   r   ÚPulseÚWaveformrs   r   ÚPlay)r'  r  r:   s      r-   Úplayr-  þ  sN   € õ( �e�Wœ]Ñ+Ô+ð (ÝÔ  Ñ'Ô'ˆå•|Ô(¨°¸dÐCÑCÔCÑDÔDÐDÐDÐDr/   c                  óB   — e Zd ZU ded<   ded<   ded<   ded<   d	ed
<   dS )Ú_MetaDataTypezconfiguration.KernelÚkernelzconfiguration.DiscriminatorÚdiscriminatorzchans.MemorySlotÚmem_slotzchans.RegisterSlotÚreg_slotrt   r:   N)rH   r¯   r°   Ú__annotations__r¸   r/   r-   r/  r/    sI   € € € € € € Ø Ð Ð Ñ Ø.Ð.Ð.Ñ.ØÐÐÑØ Ð Ð Ñ Ø€I€I�I€I€Ir/   r/  )ÚtotalÚqubit_or_channelúint | chans.AcquireChannelr¶   ÚStorageLocationÚmetadataúUnpack[_MetaDataType]c                ó–  — t          |t          ¦  «        rt          j        |¦  «        }t          |t          j        ¦  «        r$t          t          j        | |fd|i|¤Ž¦  «         dS t          |t          j        ¦  «        r$t          t          j        | |fd|i|¤Ž¦  «         dS t          j
        dt          |¦  «        › d�¦  «        ‚)a"  Acquire for a ``duration`` on a ``channel`` and store the result
    in a ``register``.

    Examples:

    .. code-block::

        from qiskit import pulse

        acq0 = pulse.AcquireChannel(0)
        mem0 = pulse.MemorySlot(0)

        with pulse.build() as pulse_prog:
            pulse.acquire(100, acq0, mem0)

            # measurement metadata
            kernel = pulse.configuration.Kernel('linear_discriminator')
            pulse.acquire(100, acq0, mem0, kernel=kernel)

    .. note:: The type of data acquire will depend on the execution ``meas_level``.

    Args:
        duration: Duration to acquire data for
        qubit_or_channel: Either the qubit to acquire data for or the specific
            :class:`~qiskit.pulse.channels.AcquireChannel` to acquire on.
        register: Location to store measured result.
        metadata: Additional metadata for measurement. See
            :class:`~qiskit.pulse.instructions.Acquire` for more information.

    Raises:
        exceptions.PulseError: If the register type is not supported.
    r2  r3  zRegister of type: "z" is not supportedN)rD   rÈ   ræ   ÚAcquireChannelÚ
MemorySlotrs   r   ÚAcquireÚRegisterSlotr   rF   Útype)rô   r6  r¶   r9  s       r-   r  r     sô   € õN Ð"¥CÑ(Ô(ð BÝ Ô/Ð0@ÑAÔAÐå�(�EÔ,Ñ-Ô-ð 	^ÝÝÔ  Ð+;Ð[Ð[ÀhÐ[ÐRZÐ[Ð[ñ	
ô 	
ð 	
ð 	
ð 	
õ 
�H�eÔ0Ñ	1Ô	1ð ^ÝÝÔ  Ð+;Ð[Ð[ÀhÐ[ÐRZÐ[Ð[ñ	
ô 	
ð 	
ð 	
ð 	
õ Ô#Ð$\½$¸x¹.¼.Ð$\Ð$\Ð$\Ñ]Ô]Ð]r/   c                óN   — t          t          j        | ||¬¦  «        ¦  «         dS )a†  Set the ``frequency`` of a pulse ``channel``.

    Examples:

    .. code-block::

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.set_frequency(1e9, d0)

    Args:
        frequency: Frequency in Hz to set channel to.
        channel: Channel to set frequency of.
        name: Name of the instruction.
    r¤   N)rs   r   ÚSetFrequency©r  r  r:   s      r-   Úset_frequencyrD  V  s*   € õ( •|Ô0°¸GÈ$ÐOÑOÔOÑPÔPÐPÐPÐPr/   c                óN   — t          t          j        | ||¬¦  «        ¦  «         dS )a»  Shift the ``frequency`` of a pulse ``channel``.

    Examples:

    .. code-block:: python
        :emphasize-lines: 6

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.shift_frequency(1e9, d0)

    Args:
        frequency: Frequency in Hz to shift channel frequency by.
        channel: Channel to shift frequency of.
        name: Name of the instruction.
    r¤   N)rs   r   ÚShiftFrequencyrC  s      r-   r  r  m  s*   € õ* •|Ô2°9¸gÈDÐQÑQÔQÑRÔRÐRÐRÐRr/   c                óN   — t          t          j        | ||¬¦  «        ¦  «         dS )aÂ  Set the ``phase`` of a pulse ``channel``.

    Examples:

    .. code-block:: python
        :emphasize-lines: 8

        import math

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.set_phase(math.pi, d0)

    Args:
        phase: Phase in radians to set channel carrier signal to.
        channel: Channel to set phase of.
        name: Name of the instruction.
    r¤   N)rs   r   ÚSetPhase©r   r  r:   s      r-   Ú	set_phaserJ  …  s*   € õ. •|Ô,¨U°GÀ$ÐGÑGÔGÑHÔHÐHÐHÐHr/   c                óL   — t          t          j        | ||¦  «        ¦  «         dS )a§  Shift the ``phase`` of a pulse ``channel``.

    Examples:

    .. code-block::

        import math

        from qiskit import pulse

        d0 = pulse.DriveChannel(0)

        with pulse.build() as pulse_prog:
            pulse.shift_phase(math.pi, d0)

    Args:
        phase: Phase in radians to shift channel carrier signal by.
        channel: Channel to shift phase of.
        name: Name of the instruction.
    N)rs   r   Ú
ShiftPhaserI  s      r-   r  r  Ÿ  s'   € õ, •|Ô.¨u°g¸tÑDÔDÑEÔEÐEÐEÐEr/   ÚstatevectorÚlabelrt   Úsnapshot_typec                óL   — t          t          j        | |¬¦  «        ¦  «         dS )a  Simulator snapshot.

    Examples:

    .. code-block::

        from qiskit import pulse

        with pulse.build() as pulse_prog:
            pulse.snapshot('first', 'statevector')

    Args:
        label: Label for snapshot.
        snapshot_type: Type of snapshot.
    )rO  N)rs   r   ÚSnapshot)rN  rO  s     r-   ÚsnapshotrR  ¸  s(   € õ" •|Ô,¨UÀ-ÐPÑPÔPÑQÔQÐQÐQÐQr/   ÚtargetúSchedule | ScheduleBlock | Noner~   ú3dict[ParameterValueType, ParameterValueType] | Noner€   r   c                ó>   —  t          ¦   «         j        | ||fi |¤Ž dS )a<  Call the subroutine within the currently active builder context with arbitrary
    parameters which will be assigned to the target program.

    .. note::

        If the ``target`` program is a :class:`.ScheduleBlock`, then a :class:`.Reference`
        instruction will be created and appended to the current context.
        The ``target`` program will be immediately assigned to the current scope as a subroutine.
        If the ``target`` program is :class:`.Schedule`, it will be wrapped by the
        :class:`.Call` instruction and appended to the current context to avoid
        a mixed representation of :class:`.ScheduleBlock` and :class:`.Schedule`.
        If the ``target`` program is a :class:`.QuantumCircuit` it will be scheduled
        and the new :class:`.Schedule` will be added as a :class:`.Call` instruction.

    Examples:

        1. Calling a schedule block (recommended)

        .. code-block::

            from qiskit import circuit, pulse
            from qiskit.providers.fake_provider import GenericBackendV2

            backend = GenericBackendV2(num_qubits=5, calibrate_instructions=True)

            with pulse.build() as x_sched:
                pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0))

            with pulse.build() as pulse_prog:
                pulse.call(x_sched)

            print(pulse_prog)

        .. code-block:: text

            ScheduleBlock(
                ScheduleBlock(
                    Play(
                        Gaussian(duration=160, amp=(0.1+0j), sigma=40),
                        DriveChannel(0)
                    ),
                    name="block0",
                    transform=AlignLeft()
                ),
                name="block1",
                transform=AlignLeft()
            )

        The actual program is stored in the reference table attached to the schedule.

        .. code-block::

            print(pulse_prog.references)

        .. code-block:: text

            ReferenceManager:
              - ('block0', '634b3b50bd684e26a673af1fbd2d6c81'): ScheduleBlock(Play(Gaussian(...

        In addition, you can call a parameterized target program with parameter assignment.

        .. code-block::

            amp = circuit.Parameter("amp")

            with pulse.build() as subroutine:
                pulse.play(pulse.Gaussian(160, amp, 40), pulse.DriveChannel(0))

            with pulse.build() as pulse_prog:
                pulse.call(subroutine, amp=0.1)
                pulse.call(subroutine, amp=0.3)

            print(pulse_prog)

        .. code-block:: text

            ScheduleBlock(
                ScheduleBlock(
                    Play(
                        Gaussian(duration=160, amp=(0.1+0j), sigma=40),
                        DriveChannel(0)
                    ),
                    name="block2",
                    transform=AlignLeft()
                ),
                ScheduleBlock(
                    Play(
                        Gaussian(duration=160, amp=(0.3+0j), sigma=40),
                        DriveChannel(0)
                    ),
                    name="block2",
                    transform=AlignLeft()
                ),
                name="block3",
                transform=AlignLeft()
            )

        If there is a name collision between parameters, you can distinguish them by specifying
        each parameter object in a python dictionary. For example,

        .. code-block::

            amp1 = circuit.Parameter('amp')
            amp2 = circuit.Parameter('amp')

            with pulse.build() as subroutine:
                pulse.play(pulse.Gaussian(160, amp1, 40), pulse.DriveChannel(0))
                pulse.play(pulse.Gaussian(160, amp2, 40), pulse.DriveChannel(1))

            with pulse.build() as pulse_prog:
                pulse.call(subroutine, value_dict={amp1: 0.1, amp2: 0.3})

            print(pulse_prog)

        .. code-block:: text

            ScheduleBlock(
                ScheduleBlock(
                    Play(Gaussian(duration=160, amp=(0.1+0j), sigma=40), DriveChannel(0)),
                    Play(Gaussian(duration=160, amp=(0.3+0j), sigma=40), DriveChannel(1)),
                    name="block4",
                    transform=AlignLeft()
                ),
                name="block5",
                transform=AlignLeft()
            )

        2. Calling a schedule

        .. code-block::

            x_sched = backend.instruction_schedule_map.get("x", (0,))

            with pulse.build(backend) as pulse_prog:
                pulse.call(x_sched)

            print(pulse_prog)

        .. code-block:: text

            ScheduleBlock(
                Call(
                    Schedule(
                        (
                            0,
                            Play(
                                Drag(
                                    duration=160,
                                    amp=(0.18989731546729305+0j),
                                    sigma=40,
                                    beta=-1.201258305015517,
                                    name='drag_86a8'
                                ),
                                DriveChannel(0),
                                name='drag_86a8'
                            )
                        ),
                        name="x"
                    ),
                    name='x'
                ),
                name="block6",
                transform=AlignLeft()
            )

        Currently, the backend calibrated gates are provided in the form of :class:`~.Schedule`.
        The parameter assignment mechanism is available also for schedules.
        However, the called schedule is not treated as a reference.


    Args:
        target: Target circuit or pulse schedule to call.
        name: Optional. A unique name of subroutine if defined. When the name is explicitly
            provided, one cannot call different schedule blocks with the same name.
        value_dict: Optional. Parameters assigned to the ``target`` program.
            If this dictionary is provided, the ``target`` program is copied and
            then stored in the main built schedule and its parameters are assigned to the given values.
            This dictionary is keyed on :class:`~.Parameter` objects,
            allowing parameter name collision to be avoided.
        kw_params: Alternative way to provide parameters.
            Since this is keyed on the string parameter name,
            the parameters having the same name are all updated together.
            If you want to avoid name collision, use ``value_dict`` with :class:`~.Parameter`
            objects instead.
    N)rÁ   r‚   )rS  r:   r~   r€   s       r-   ÚcallrW  Ì  s0   € ð@ &…OÑÔÔ% f¨d°JÐLÐLÀ)ÐLÐLÐLÐLÐLr/   ru   c                ó:   —  t          ¦   «         j        | g|¢R Ž  dS )a­  Refer to undefined subroutine by string keys.

    A :class:`~qiskit.pulse.instructions.Reference` instruction is implicitly created
    and a schedule can be separately registered to the reference at a later stage.

    .. code-block:: python

        from qiskit import pulse

        with pulse.build() as main_prog:
            pulse.reference("x_gate", "q0")

        with pulse.build() as subroutine:
            pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0))

        main_prog.assign_references(subroutine_dict={("x_gate", "q0"): subroutine})

    Args:
        name: Name of subroutine.
        extra_keys: Helper keys to uniquely specify the subroutine.
    N)rÁ   ry   )r:   ru   s     r-   Ú	referencerY  �  s+   € ð. '…OÑÔÔ& tÐ9¨jÐ9Ð9Ð9Ð9Ð9Ð9r/   r¤   úchans.Channel | intc                ó~   — t          |Ž }t          |¦  «        dk    r t          t          j        |d| iŽ¦  «         dS dS )aà	  Barrier directive for a set of channels and qubits.

    This directive prevents the compiler from moving instructions across
    the barrier. Consider the case where we want to enforce that one pulse
    happens after another on separate channels, this can be done with:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        d0 = pulse.DriveChannel(0)
        d1 = pulse.DriveChannel(1)

        with pulse.build(backend) as barrier_pulse_prog:
            pulse.play(pulse.Constant(10, 1.0), d0)
            pulse.barrier(d0, d1)
            pulse.play(pulse.Constant(10, 1.0), d1)

    Of course this could have been accomplished with:

    .. code-block::

        from qiskit.pulse import transforms

        with pulse.build(backend) as aligned_pulse_prog:
            with pulse.align_sequential():
                pulse.play(pulse.Constant(10, 1.0), d0)
                pulse.play(pulse.Constant(10, 1.0), d1)

        barrier_pulse_prog = transforms.target_qobj_transform(barrier_pulse_prog)
        aligned_pulse_prog = transforms.target_qobj_transform(aligned_pulse_prog)

        assert barrier_pulse_prog == aligned_pulse_prog

    The barrier allows the pulse compiler to take care of more advanced
    scheduling alignment operations across channels. For example
    in the case where we are calling an outside circuit or schedule and
    want to align a pulse at the end of one call:

    .. code-block::

        import math
        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        d0 = pulse.DriveChannel(0)

        with pulse.build(backend) as pulse_prog:
            with pulse.align_right():
                pulse.call(backend.defaults().instruction_schedule_map.get('u1', (1,)))
                # Barrier qubit 1 and d0.
                pulse.barrier(1, d0)
                # Due to barrier this will play before the gate on qubit 1.
                pulse.play(pulse.Constant(10, 1.0), d0)
                # This will end at the same time as the pulse above due to
                # the barrier.
                pulse.call(backend.defaults().instruction_schedule_map.get('u1', (1,)))

    .. note:: Requires the active builder context to have a backend set if
        qubits are barriered on.

    Args:
        channels_or_qubits: Channels or qubits to barrier.
        name: Name for the barrier
    rc   r:   N)rê   rd   rs   r   ÚRelativeBarrier)r:   rã   r   s      r-   Úbarrierr]  ª  sM   € õP #Ð$6Ð7€HÝ
ˆ8�}„}�qÒÐÝ�:Ô5°xÐKÀdÐKÐKÑLÔLÐLÐLÐLð Ðr/   r   c                ó†   ‡ ‡— t          ‰ dt          ‰ ¦  «        ¦  «        Št          j        ‰ ¦  «        ˆ ˆfd„¦   «         }|S )aÇ  Wrap a Python function and activate the parent builder context at calling time.

    This enables embedding Python functions as builder macros. This generates a new
    :class:`pulse.Schedule` that is embedded in the parent builder context with
    every call of the decorated macro function. The decorated macro function will
    behave as if the function code was embedded inline in the parent builder context
    after parameter substitution.


    Examples:

    .. plot::
       :alt: Output from the previous code.
       :include-source:

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        @pulse.macro
        def measure(qubit: int):
            pulse.play(pulse.GaussianSquare(16384, 256, 15872), pulse.measure_channel(qubit))
            mem_slot = pulse.MemorySlot(qubit)
            pulse.acquire(16384, pulse.acquire_channel(qubit), mem_slot)

            return mem_slot


        backend = FakeOpenPulse2Q()

        with pulse.build(backend=backend) as sched:
            mem_slot = measure(0)
            print(f"Qubit measured into {mem_slot}")

        sched.draw()


    Args:
        func: The Python function to enable as a builder macro. There are no
            requirements on the signature of the function, any calls to pulse
            builder methods will be added to builder context the wrapped function
            is called from.

    Returns:
        Callable: The wrapped ``func``.
    rH   c                 óº   •— t          ¦   «         }t          |j        ‰¬¦  «        5 } ‰| i |¤Ž}d d d ¦  «         n# 1 swxY w Y   |                     |¦  «         |S )N)r!   r:   )rÁ   r¼   r!   r‚   )r+   r,   Ú_builderÚbuiltrU   rù   Ú	func_names        €€r-   r.   zmacro.<locals>.wrapper(  s¥   ø€ å"Ñ$Ô$ˆå˜8Ô+°)Ð<Ñ<Ô<ð 	+ÀØ�T˜4Ð* 6Ð*Ð*ˆFð	+ð 	+ð 	+ñ 	+ô 	+ð 	+ð 	+ð 	+ð 	+ð 	+ð 	+øøøð 	+ð 	+ð 	+ð 	+ð 	× Ò  Ñ'Ô'Ð'Øˆs   ¦	;»?Á?)ÚgetattrrL   r0   r1   )rù   r.   rb  s   ` @r-   Úmacrord  ø  sX   øø€ õ\ ˜˜j­$¨t©*¬*Ñ5Ô5€Iå„_�TÑÔðð ð ð ð ñ Ôðð €Nr/   úlist[int] | intÚ	registersú'list[StorageLocation] | StorageLocationc           	     óD  — t          ¦   «         }	 t          | ¦  «        } n# t          $ r | g} Y nw xY w|€d„ | D ¦   «         }n$	 t          |¦  «        }n# t          $ r |g}Y nw xY wt          j        | |d„ t          | |¦  «        D ¦   «         ¬¦  «        }d                     t          t          | ¦  «        ¦  «        }d                     d„ |D ¦   «         ¦  «        }t          ¦   «          
                    |d|› d|› �¬	¦  «         t          | ¦  «        d
k    r|d         S |S )ak  Measure a qubit within the currently active builder context.

    At the pulse level a measurement is composed of both a stimulus pulse and
    an acquisition instruction which tells the systems measurement unit to
    acquire data and process it. We provide this measurement macro to automate
    the process for you, but if desired full control is still available with
    :func:`acquire` and :func:`play`.

    To use the measurement it is as simple as specifying the qubit you wish to
    measure:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        qubit = 0

        with pulse.build(backend) as pulse_prog:
            # Do something to the qubit.
            qubit_drive_chan = pulse.drive_channel(0)
            pulse.play(pulse.Constant(100, 1.0), qubit_drive_chan)
            # Measure the qubit.
            reg = pulse.measure(qubit)

    For now it is not possible to do much with the handle to ``reg`` but in the
    future we will support using this handle to a result register to build
    up ones program. It is also possible to supply this register:

    .. code-block::

        with pulse.build(backend) as pulse_prog:
            pulse.play(pulse.Constant(100, 1.0), qubit_drive_chan)
            # Measure the qubit.
            mem0 = pulse.MemorySlot(0)
            reg = pulse.measure(qubit, mem0)

        assert reg == mem0

    .. note:: Requires the active builder context to have a backend set.

    Args:
        qubits: Physical qubit to measure.
        registers: Register to store result in. If not selected the current
            behavior is to return the :class:`MemorySlot` with the same
            index as ``qubit``. This register will be returned.
    Returns:
        The ``register`` the qubit measurement result will be stored in.
    Nc                ó6   — g | ]}t          j        |¦  «        ‘ŒS r¸   ©ræ   r=  ©Ú.0rÕ   s     r-   ú
<listcomp>zmeasure.<locals>.<listcomp>u  s#   € ÐAÐAÐA°•UÔ% eÑ,Ô,ÐAÐAÐAr/   c                ó$   — i | ]\  }}||j         “ŒS r¸   )Úindex)rl  rÕ   r¶   s      r-   ú
<dictcomp>zmeasure.<locals>.<dictcomp>~  s    € Ð]Ð]Ð]±?°5¸(˜ ¤Ð]Ð]Ð]r/   ©r  r!   Úqubit_mem_slotsú&c              3  ó>   K  — | ]}t          |j        ¦  «        V — Œd S ©N)rt   ro  )rl  Úrs     r-   ú	<genexpr>zmeasure.<locals>.<genexpr>…  s*   è è € Ð<Ð<¨Q�C ¤™LœLÐ<Ð<Ð<Ð<Ð<Ð<r/   Úmeasure_z..r¤   rc   r   )rÄ   ÚlistÚ	TypeErrorr   r  ÚziprM   r‹   rt   rÁ   r‚   rd   )r  rf  r!   Úmeasure_schedÚqubits_reprÚmslots_reprs         r-   r  r  5  sd  € õp ÑÔ€GðÝ�f‘”ˆˆøÝð ð ð Ø�ˆˆˆðøøøð ÐØAÐA¸&ÐAÑAÔAˆ	ˆ	ð	$Ý˜Y™œˆIˆIøÝð 	$ð 	$ð 	$Ø"˜ˆIˆIˆIð	$øøøå”NØØØ]Ð]ÅcÈ&ÐR[ÑF\ÔF\Ð]Ñ]Ô]ðñ ô €Mð —(’(�3�s FÑ+Ô+Ñ,Ô,€KØ—(’(Ð<Ð<°)Ð<Ñ<Ô<Ñ=Ô=€KÝÑÔ×%Ò% mÐ:aÀ[Ð:aÐ:aÐT_Ð:aÐ:aÐ%ÑbÔbÐbå
ˆ6�{„{�aÒÐØ˜Œ|ÐàÐs   �   0¯0ÁA ÁA#Á"A#úlist[chans.MemorySlot]c                 óø   — t          ¦   «         } t          t          ¦   «         ¦  «        }d„ |D ¦   «         }t          j        || d„ |D ¦   «         ¬¦  «        }t          ¦   «                              |d¬¦  «         |S )aï  Measure all qubits within the currently active builder context.

    A simple macro function to measure all of the qubits in the device at the
    same time. This is useful for handling device ``meas_map`` and single
    measurement constraints.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse2Q

        backend = FakeOpenPulse2Q()

        with pulse.build(backend) as pulse_prog:
            # Measure all qubits and return associated registers.
            regs = pulse.measure_all()

    .. note::
        Requires the active builder context to have a backend set.

    Returns:
        The ``register``\s the qubit measurement results will be stored in.
    c                ó6   — g | ]}t          j        |¦  «        ‘ŒS r¸   rj  rk  s     r-   rm  zmeasure_all.<locals>.<listcomp>«  s#   € Ð=Ð=Ð=¨U•Ô! %Ñ(Ô(Ð=Ð=Ð=r/   c                ó   — i | ]}||“ŒS r¸   r¸   rk  s     r-   rp  zmeasure_all.<locals>.<dictcomp>°  s   € Ð:Ð:Ð:¨%˜ Ð:Ð:Ð:r/   rq  Úmeasure_allr¤   )rÄ   Úrangerk   r   r  rÁ   r‚   )r!   r  rf  r|  s       r-   rƒ  rƒ  Ž  s‡   € õ6 ÑÔ€GÝ•:‘<”<Ñ Ô €FØ=Ð=°fÐ=Ñ=Ô=€Iå”NØØØ:Ð:°6Ð:Ñ:Ô:ðñ ô €Mõ ÑÔ×%Ò% m¸-Ð%ÑHÔHÐHàÐr/   c                óì   — t          t          j                             d„ |D ¦   «         ¦  «        ¦  «        }t	          ¦   «         5  |D ]}t          | |¦  «         Œ	 ddd¦  «         dS # 1 swxY w Y   dS )aÓ  Insert delays on all the :class:`channels.Channel`\s that correspond
    to the input ``qubits`` at the same time.

    Examples:

    .. code-block::

        from qiskit import pulse
        from qiskit.providers.fake_provider import FakeOpenPulse3Q

        backend = FakeOpenPulse3Q()

        with pulse.build(backend) as pulse_prog:
            # Delay for 100 cycles on qubits 0, 1 and 2.
            regs = pulse.delay_qubits(100, 0, 1, 2)

    .. note:: Requires the active builder context to have a backend set.

    Args:
        duration: Duration to delay for.
        qubits: Physical qubits to delay on. Delays will be inserted based on
            the channels returned by :func:`pulse.qubit_channels`.
    c              3  ó4   K  — | ]}t          |¦  «        V — Œd S ru  )râ   rk  s     r-   rw  zdelay_qubits.<locals>.<genexpr>Ó  s*   è è € Ð3^Ð3^ÈeµNÀ5Ñ4IÔ4IÐ3^Ð3^Ð3^Ð3^Ð3^Ð3^r/   N)rT   Ú	itertoolsÚchainÚfrom_iterablerî   r&  )rô   r  Úqubit_chansÚchans       r-   Údelay_qubitsrŒ  º  sÆ   € õ2 •i”o×3Ò3Ð3^Ð3^ÐW]Ð3^Ñ3^Ô3^Ñ^Ô^Ñ_Ô_€KÝ	‰Œð "ð "Øð 	"ð 	"ˆDÝ�(˜DÑ!Ô!Ð!Ð!ð	"ð"ð "ð "ñ "ô "ð "ð "ð "ð "ð "ð "ð "øøøð "ð "ð "ð "ð "ð "s   ÁA)Á)A-Á0A-)r$   r%   r&   r%   r«   )rž   r9   r:   r;   r<   r¹   r&   rº   )r&   r4   )rž   r{   r¬   )r&   rÈ   )rÊ   rË   r&   rÌ   )rÒ   rÌ   r&   rË   )rÕ   rÈ   r&   rÖ   )rã   rä   r&   rÖ   )r&   rë   )rô   rõ   r&   rë   )rô   rõ   rù   rú   r&   rë   )ra   r   r&   rë   )r   r  r   r  r&   rë   )r  r  r   r  r  r	  r&   rë   )rÕ   rÈ   r&   r  )rÕ   rÈ   r&   r  )rÕ   rÈ   r&   r  )r  r  r&   r  ru  )rô   rÈ   r  r#  r:   r;   )r'  r(  r  r  r:   r;   )rô   rÈ   r6  r7  r¶   r8  r9  r:  )r  r  r  r  r:   r;   )r   r  r  r  r:   r;   )rM  )rN  rt   rO  rt   r®   )rS  rT  r:   r;   r~   rU  r€   r   r­   )rã   rZ  r:   r;   )rù   r   )r  re  rf  rg  r&   rg  )r&   r  )rô   rÈ   r  rÈ   )br±   Ú
__future__r   Úcontextvarsr0   r‡  Úsysr’   r�   Úcollections.abcr   r   r   Ú
contextlibr   r   Útypingr	   r
   r   r   r   r   ÚnumpyrÎ   Ú"qiskit.circuit.parameterexpressionr   r   Úqiskit.pulser   ræ   r   r   r   r   r   r   Úqiskit.providers.backendr   Úqiskit.pulse.instructionsr   Úqiskit.pulse.scheduler   r   Ú"qiskit.pulse.transforms.alignmentsr   Úqiskit.utils.deprecate_pulser   Úversion_infor    Útyping_extensionsÚ
ContextVarr"   r4  r#   r=  r?  r8  r2   r4   r¼   rÁ   rÄ   rÆ   rs   rk   rÑ   rÔ   râ   rê   rî   rñ   ró   rø   rý   rÿ   r  r  rÜ   rÝ   rÞ   r"  r&  r-  r/  r  rD  r  rJ  r  rR  rW  rY  r]  rd  r  rƒ  rŒ  r¸   r/   r-   ú<module>rž     s<  ððRð Rð Rðf #Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø €€€Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø %Ð %Ð %Ð %Ð %Ð %Ø *Ð *Ð *Ð *Ð *Ð *Ø LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ LÐ Là Ð Ð Ð à VÐ VÐ VÐ VÐ VÐ VÐ VÐ Vðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð /Ð .Ð .Ð .Ð .Ð .Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø <Ð <Ð <Ð <Ð <Ð <Ø =Ð =Ð =Ð =Ð =Ð =ð Ô�wÒÐØÐÐÐÐÐÐà(Ð(Ð(Ð(Ð(Ð(ð ?U¸kÔ>TÐU^Ñ>_Ô>_Ð Ð _Ð _Ð _Ñ _à€GˆC�L„L€à˜Ô(¨%Ô*<Ð<Ô=€ðð ð ð ð o/ð o/ð o/ð o/ð o/ñ o/ô o/ð o/ðd	 àØ%)ØØ4:ð	/ð /ð /ð /ñ Ôð/ðjð ð ð ð( ðð ñ Ôðð$2ð 2ð 2ð 2ð6ð 6ð 6ð 6ð. ð5ð 5ð 5ñ Ôð5ð4 ðð ð ñ Ôðð$ ð
0ð 
0ð 
0ñ Ôð
0ð ð2Kð 2Kð 2Kñ Ôð2Kðjð ð ð ð$ Øð"+ð "+ð "+ñ Ôñ „ð"+ðJ Øð"+ð "+ð "+ñ Ôñ „ð"+ðJ Øð"+ð "+ð "+ñ Ôñ „ð"+ðJ Øð1+ð 1+ð 1+ñ Ôñ „ð1+ðh Øð;+ð ;+ð ;+ñ Ôñ „ð;+ð| ð+ð +ð +ñ „ð+ð2 Øð )ð  )ð  )ñ Ôñ „ð )ðF ØàNSð=1ð =1ð =1ð =1ð =1ñ Ôñ „ð=1ðB ð9ð 9ð 9ñ Ôð9ð. ð;ð ;ð ;ñ Ôð;ð. ð;ð ;ð ;ñ Ôð;ð. ðCð Cð Cñ ÔðCðD ðIð Ið Ið Iñ ÔðIð, ðEð Eð Eð Eñ ÔðEð2ð ð ð ð �I Uð ñ ô ð ð ð2^ð 2^ð 2^ñ Ôð2^ðj ðQð Qð Qð Qñ ÔðQð, ðSð Sð Sð Sñ ÔðSð. ðIð Ið Ið Iñ ÔðIð2 ðFð Fð Fð Fñ ÔðFð0 ðRð Rð Rð Rñ ÔðRð& ð ØFJðMð Mð Mð Mñ ÔðMðD ð:ð :ð :ñ Ôð:ð4 ØIMð IMð IMð IMð IMð IMñ ÔðIMðZ:ð :ð :ð :ðz ð :>ðUð Uð Uð Uñ ÔðUðp ð(ð (ð (ñ Ôð(ðV ð"ð "ð "ñ Ôð"ð "ð "r/   