2.10. Abstract Pulse Template

This pulse template can be used as a place holder for a pulse template with a defined interface. Pulse template properties like defined_channels can be passed on initialization to declare those properties who make up the interface. Omitted properties raise an NotSpecifiedError exception if accessed. Properties which have been accessed are marked as “frozen”. The abstract pulse template can be linked to another pulse template by calling the link_to member. The target has to have the same properties for all properties marked as “frozen”. This ensures a property always returns the same value.

[1]:
from qupulse.pulses import AbstractPT, FunctionPT, AtomicMultiChannelPT, PointPT

init = PointPT([(0, (1, 0)), ('t_init', (0, 1), 'linear')], ['X', 'Y'])
abstract_readout = AbstractPT('readout', defined_channels={'X', 'Y'}, integral={'X': 1, 'Y': 'a*b'})
manip = AtomicMultiChannelPT(FunctionPT('sin(t)', 't_manip', channel='X'),
                             FunctionPT('cos(t)', 't_manip', channel='Y'))

experiment = init @ manip @ abstract_readout

We can access declared properties like integral. If we try to get a non-declared property an exception is raised.

[2]:
print('The integral has been declared so we can get it')
print(experiment.integral)
print()

import traceback
try:
    experiment.duration
except Exception as err:
    print('We get an error that for the pulse "readout" the property "duration" was not specified:')
    print(repr(err))
The integral has been declared so we can get it
{'Y': Expression('a*b + sin(t_manip)'), 'X': Expression('t_init - cos(t_manip) + 2')}

We get an error that for the pulse "readout" the property "duration" was not specified:
NotSpecifiedError('readout', 'duration')

We can link the abstract pulse template to an actual pulse template. By accessing the integral property above we froze it. Linking a pulse with a different property will result in an error.

[3]:
my_readout_wrong_integral = AtomicMultiChannelPT(FunctionPT('1', 't_read', channel='X'),
                                                 FunctionPT('a*b', 't_read', channel='Y'))

my_readout = AtomicMultiChannelPT(FunctionPT('1 / t_read', 't_read', channel='X'),
                                  FunctionPT('a*b / t_read', 't_read', channel='Y'))

try:
    print('With wrong integral value:')
    abstract_readout.link_to(my_readout_wrong_integral)
except Exception as err:
    print(repr(err))

abstract_readout.link_to(my_readout)
print('the linking worked.  The new experiment has now a defined duration of', repr(experiment.duration), '.')
With wrong integral value:
RuntimeError('Cannot link to target. Wrong value of property "integral"')
the linking worked.  The new experiment has now a defined duration of Expression('t_init + t_manip + t_read') .