|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +import numpy as np |
| 3 | + |
| 4 | +from qupulse.pulses import PointPT, ConstantPT, RepetitionPT, ForLoopPT, TablePT,\ |
| 5 | + FunctionPT, AtomicMultiChannelPT, SequencePT, MappingPT, ParallelConstantChannelPT |
| 6 | +from qupulse.program.linspace import LinSpaceBuilder |
| 7 | + |
| 8 | +from qupulse.plotting import plot |
| 9 | +from qupulse.utils import to_next_multiple |
| 10 | + |
| 11 | +from expectation_checker import ExpectationChecker, HDAWGAlazar |
| 12 | + |
| 13 | +#%% Get Devices |
| 14 | + |
| 15 | +# Get the Alazar and the HDAWG in hardcoded configuration (2V p-p range) |
| 16 | +# Connect any Marker from the HDAWG to Trig in of the Alazar |
| 17 | +# Connect one dummy channel from HDAWG to the external clock of the Alazar, |
| 18 | +# then set 0.5V-10MHz-oscillator on this channel (e.g. in HDAWG-Webinterface) |
| 19 | + |
| 20 | +ha = HDAWGAlazar("DEVXXXX","USB",) |
| 21 | + |
| 22 | +#%% Example pulse definitions |
| 23 | + |
| 24 | +# PulseTemplates must be defined on channels named as 'ZI0_X', X in A to H |
| 25 | +# (ensure correct mapping to Alazar) |
| 26 | +# Markers will be overwritten to play a marker on each channel to trigger the Alazar |
| 27 | +# identifiers of the final PT will be the names of the plotted object |
| 28 | + |
| 29 | + |
| 30 | +class ShortSingleRampTest(): |
| 31 | + def __init__(self, base_time=1e3): |
| 32 | + hold = ConstantPT(base_time, {'a': '-1. + idx * 0.01'}) |
| 33 | + pt = hold.with_iteration('idx', 200) |
| 34 | + self.pulse_template = MappingPT(pt, |
| 35 | + channel_mapping={'a':'ZI0_A',}, |
| 36 | + identifier=self.__class__.__name__ |
| 37 | + ) |
| 38 | + |
| 39 | +class ShortSingleRampTestWithPlay(): |
| 40 | + def __init__(self,base_time=1e3+8): |
| 41 | + # init = PointPT([(1.0,1e4)],channel_names=('ZI0_MARKER_FRONT',)) |
| 42 | + init = FunctionPT('1.0+1e-9*t',base_time,channel='ZI0_A_MARKER_FRONT')#.pad_to(to_next_multiple(1.0,16,4),) |
| 43 | + |
| 44 | + hold = ConstantPT(base_time, {'a': '-1. + idx * 0.01'})#.pad_to(to_next_multiple(1.0,16,4)) |
| 45 | + pt = ParallelConstantChannelPT(init,dict(ZI0_A=0.))@(ParallelConstantChannelPT(hold,dict(ZI0_A_MARKER_FRONT=0.)).with_iteration('idx', 200)) |
| 46 | + self.pulse_template = MappingPT(pt, |
| 47 | + channel_mapping={'a':'ZI0_A',}, |
| 48 | + identifier=self.__class__.__name__ |
| 49 | + ) |
| 50 | + |
| 51 | +class SequencedRepetitionTest(): |
| 52 | + def __init__(self,base_time=1e2,rep_factor=2): |
| 53 | + wait = AtomicMultiChannelPT( |
| 54 | + ConstantPT(f'64*{base_time}', {'a': '-1. + idx_a * 0.01 + y_gain', }), |
| 55 | + ConstantPT(f'64*{base_time}', {'b': '-0.5 + idx_b * 0.02'}) |
| 56 | + ) |
| 57 | + |
| 58 | + dependent_constant = AtomicMultiChannelPT( |
| 59 | + ConstantPT(64*base_time, {'a': '-1.0 + y_gain'}), |
| 60 | + ConstantPT(64*base_time, {'b': '-0.5 + idx_b*0.02',}), |
| 61 | + ) |
| 62 | + |
| 63 | + dependent_constant2 = AtomicMultiChannelPT( |
| 64 | + ConstantPT(64*base_time, {'a': '-0.5 + y_gain'}), |
| 65 | + ConstantPT(64*base_time, {'b': '-0.3 + idx_b*0.02',}), |
| 66 | + ) |
| 67 | + |
| 68 | + |
| 69 | + pt = (dependent_constant @ dependent_constant2.with_repetition(rep_factor) @ (wait.with_iteration('idx_a', rep_factor))).with_iteration('idx_b', rep_factor)\ |
| 70 | + |
| 71 | + self.pulse_template = MappingPT(pt,parameter_mapping=dict(y_gain=0.3,), |
| 72 | + channel_mapping={'a':'ZI0_A','b':'ZI0_C'}, |
| 73 | + identifier=self.__class__.__name__ |
| 74 | + ) |
| 75 | + |
| 76 | + |
| 77 | +class SteppedRepetitionTest(): |
| 78 | + def __init__(self,base_time=1e2,rep_factor=2): |
| 79 | + |
| 80 | + wait = ConstantPT(f'64*{base_time}*(1+idx_t)', {'a': '-0.5 + idx_a * 0.15', 'b': '-.5 + idx_a * 0.3'}) |
| 81 | + normal_pt = ParallelConstantChannelPT(FunctionPT("sin(t/1000)","t_sin",channel='a'),{'b':-0.2}) |
| 82 | + amp_pt = ParallelConstantChannelPT("amp*1/8"*FunctionPT("sin(t/2000)","t_sin",channel='a'),{'b':-0.5}) |
| 83 | + # amp_pt2 = ParallelConstantChannelPT("amp2*1/8"*FunctionPT("sin(t/1000)","t_sin",channel='a'),{'b':-0.5}) |
| 84 | + amp_inner = ParallelConstantChannelPT(FunctionPT(f"(1+amp)*1/(2*{rep_factor})*sin(4*pi*t/t_sin)","t_sin",channel='a'),{'b':-0.5}) |
| 85 | + amp_inner2 = ParallelConstantChannelPT(FunctionPT(f"(1+amp2)*1/(2*{rep_factor})*sin((1*freq)*4*pi*t/t_sin)+off/(2*{rep_factor})","t_sin",channel='a'),{'b':-0.3}) |
| 86 | + |
| 87 | + pt = ((((normal_pt@amp_inner2).with_iteration('off', rep_factor)@normal_pt@wait)\ |
| 88 | + .with_repetition(rep_factor))@amp_inner.with_iteration('amp', rep_factor))\ |
| 89 | + .with_iteration('amp2', rep_factor).with_iteration('freq', rep_factor).with_iteration('idx_a',rep_factor) |
| 90 | + |
| 91 | + self.pulse_template = MappingPT(pt,parameter_mapping=dict(t_sin=64*base_time,idx_t=1, |
| 92 | + #idx_a=1,#freq=1,#amp2=1 |
| 93 | + ), |
| 94 | + channel_mapping={'a':'ZI0_A','b':'ZI0_C'}, |
| 95 | + identifier=self.__class__.__name__) |
| 96 | + |
| 97 | +class TimeSweepTest(): |
| 98 | + def __init__(self,base_time=1e2,rep_factor=3): |
| 99 | + wait = ConstantPT(f'64*{base_time}*(1+idx_t)', |
| 100 | + {'a': '-1. + idx_a * 0.01', 'b': '-.5 + idx_b * 0.02'}) |
| 101 | + |
| 102 | + random_constant = ConstantPT(64*base_time, {'a': -.4, 'b': -.3}) |
| 103 | + meas = ConstantPT(64*base_time, {'a': 0.05, 'b': 0.06}) |
| 104 | + |
| 105 | + singlet_scan = (SequencePT(random_constant,wait,meas,identifier='s')).with_iteration('idx_a', rep_factor)\ |
| 106 | + .with_iteration('idx_b', rep_factor)\ |
| 107 | + .with_iteration('idx_t', rep_factor) |
| 108 | + |
| 109 | + self.pulse_template = MappingPT(singlet_scan,channel_mapping={'a':'ZI0_A','b':'ZI0_C'}, |
| 110 | + identifier=self.__class__.__name__) |
| 111 | + |
| 112 | + |
| 113 | +#%% Instantiate Checker |
| 114 | + |
| 115 | +# select exemplary pulse |
| 116 | +pulse = ShortSingleRampTest(1e3+8) |
| 117 | +# pulse = ShortSingleRampTestWithPlay() |
| 118 | +# pulse = SequencedRepetitionTest(1e3,4) |
| 119 | +# pulse = SteppedRepetitionTest(1e2,3) |
| 120 | +# pulse = TimeSweepTest(1e2,3) |
| 121 | + |
| 122 | +# Define a program builder to test program with: |
| 123 | +program_builder = LinSpaceBuilder( |
| 124 | + #set to True to ensure triggering at Program start if program starts with constant pulse |
| 125 | + play_marker_when_constant=True, |
| 126 | + #in case stepped repetitions are needed, insert variables here: |
| 127 | + to_stepping_repeat={'example',}, |
| 128 | + ) |
| 129 | + |
| 130 | +# Data will be saved as xr.Dataset in save_path |
| 131 | +# data_offsets corrects for offsets in Alazar (not in saved data, only in plotting) |
| 132 | +checker = ExpectationChecker(ha, pulse.pulse_template, |
| 133 | + program_builder=program_builder, |
| 134 | + save_path=SAVE_HERE, |
| 135 | + data_offsets={'t_offset':-100.,'v_offset':0.008,'v_scale':0.9975} |
| 136 | + ) |
| 137 | + |
| 138 | +assert float(pulse.pulse_template.duration) < 1e7, "Ensure you know what you're doing when recording long data" |
| 139 | + |
| 140 | +#%% Run the checker |
| 141 | + |
| 142 | +checker.run() |
0 commit comments