|
11 | 11 | # # |
12 | 12 | ##################################################################### |
13 | 13 |
|
14 | | -import __init__ # only have to do this because we're inside the labscript directory |
15 | | -from labscript import * |
| 14 | +import numpy as np |
| 15 | +from labscript import ( |
| 16 | + AnalogIn, |
| 17 | + AnalogOut, |
| 18 | + ClockLine, |
| 19 | + DDS, |
| 20 | + DigitalOut, |
| 21 | + MHz, |
| 22 | + Shutter, |
| 23 | + StaticDDS, |
| 24 | + WaitMonitor, |
| 25 | + start, |
| 26 | + stop, |
| 27 | + wait, |
| 28 | +) |
16 | 29 | from labscript_devices.PulseBlaster import PulseBlaster |
17 | | -from labscript_devices.NI_PCIe_6363 import NI_PCIe_6363 |
| 30 | +from labscript_devices.NI_DAQmx.labscript_devices import NI_PCIe_6363 |
18 | 31 | from labscript_devices.NovaTechDDS9M import NovaTechDDS9M |
19 | 32 | from labscript_devices.Camera import Camera |
20 | 33 | from labscript_devices.PineBlaster import PineBlaster |
21 | | -from labscript_devices.NI_PCI_6733 import NI_PCI_6733 |
22 | | -from labscript_utils.unitconversions import * |
| 34 | +from labscript_devices.NI_DAQmx.labscript_devices import NI_PCI_6733 |
| 35 | +from labscript_utils.unitconversions import example1, example2, example3 |
23 | 36 |
|
24 | | -PulseBlaster(name='pulseblaster_0', board_number=0) |
25 | | -ClockLine(name='pulseblaster_0_clockline_fast', pseudoclock=pulseblaster_0.pseudoclock, connection='flag 0') |
26 | | -ClockLine(name='pulseblaster_0_clockline_slow', pseudoclock=pulseblaster_0.pseudoclock, connection='flag 1') |
27 | | -NI_PCIe_6363(name='ni_card_0', parent_device=pulseblaster_0_clockline_fast, clock_terminal='ni_pcie_6363_0/PFI0', MAX_name='ni_pcie_6363_0', acquisition_rate=100e3) |
28 | | -NovaTechDDS9M(name='novatechdds9m_0', parent_device=pulseblaster_0_clockline_slow, com_port="com10") |
| 37 | +PulseBlaster(name="pulseblaster_0", board_number=0) |
| 38 | +ClockLine( |
| 39 | + name="pulseblaster_0_clockline_fast", |
| 40 | + pseudoclock=pulseblaster_0.pseudoclock, |
| 41 | + connection="flag 0", |
| 42 | +) |
| 43 | +ClockLine( |
| 44 | + name="pulseblaster_0_clockline_slow", |
| 45 | + pseudoclock=pulseblaster_0.pseudoclock, |
| 46 | + connection="flag 1", |
| 47 | +) |
| 48 | +NI_PCIe_6363( |
| 49 | + name="ni_card_0", |
| 50 | + parent_device=pulseblaster_0_clockline_fast, |
| 51 | + clock_terminal="ni_pcie_6363_0/PFI0", |
| 52 | + MAX_name="ni_pcie_6363_0", |
| 53 | + acquisition_rate=100e3, |
| 54 | +) |
| 55 | +NovaTechDDS9M( |
| 56 | + name="novatechdds9m_0", |
| 57 | + parent_device=pulseblaster_0_clockline_slow, |
| 58 | + com_port="com10", |
| 59 | +) |
29 | 60 |
|
30 | 61 | # Create a BIAS Camera, tirggered to take photos with flag 3 of pulseblaster_0 |
31 | | -Camera('andor_ixon_0', pulseblaster_0.direct_outputs, 'flag 3', BIAS_port = 42520, serial_number="0000", SDK="IMAQdx", effective_pixel_size=4.6e-6, exposure_time=.1, orientation='top') |
| 62 | +Camera( |
| 63 | + name="andor_ixon_0", |
| 64 | + parent_device=pulseblaster_0.direct_outputs, |
| 65 | + connection="flag 3", |
| 66 | + BIAS_port=42520, |
| 67 | + serial_number="0000", |
| 68 | + SDK="IMAQdx", |
| 69 | + effective_pixel_size=4.6e-6, |
| 70 | + exposure_time=0.1, |
| 71 | + orientation="top", |
| 72 | +) |
32 | 73 |
|
33 | 74 | # A second pseudoclock to just clock a NI_PCI_6733 Card |
34 | | -PineBlaster(name='pineblaster_0', trigger_device=ni_card_0, trigger_connection='port0/line15', usbport='COM7') |
35 | | -NI_PCI_6733(name='ni_card_1', parent_device=pineblaster_0.clockline, clock_terminal='ni_pcie_6733_0/PFI0', MAX_name='ni_pci_6733_0') |
36 | | - |
37 | | -# Create the output/input channels on the above devices |
38 | | -AnalogOut( 'analog0', ni_card_1, 'ao0', unit_conversion_class=example1) # use the example1 conversion class located in pythonlib/unitconversions/example.py with default paremeters |
39 | | - |
40 | | -# same as above, but we are changing some parameters used in the conversion and specifying a prefix to be used with units. You can now program in mA, uA, mGauss, uGauss |
41 | | -AnalogOut( 'analog1', ni_card_1, 'ao1', unit_conversion_class=example1, unit_conversion_parameters={'a':5, 'b':1, 'magnitudes':['m','u']}) |
42 | | -AnalogOut( 'analog2', ni_card_0, 'ao2') |
43 | | -AnalogIn( 'input1', ni_card_0, 'ai0') |
44 | | -Shutter( 'shutter1', ni_card_0, 'port0/line1', delay=(0,0)) |
45 | | -Shutter( 'shutter2', pulseblaster_0.direct_outputs, 'flag 2', delay=(0,0)) |
46 | | -DigitalOut( 'switch', pulseblaster_0.direct_outputs, 'flag 4') |
47 | | - |
48 | | -DDS( 'dds1', novatechdds9m_0, 'channel 0') |
49 | | -DDS( 'dds2', novatechdds9m_0, 'channel 1') |
50 | | -StaticDDS( 'dds5', novatechdds9m_0, 'channel 2') |
51 | | -# The next DDS is special because it has the frequency and amplitude calibrated using example2 and example3 classes from pythonlib/unitconversions/example.py |
52 | | -DDS( 'dds3', pulseblaster_0.direct_outputs, 'dds 0', freq_conv_class=example2, freq_conv_params={'a':4, 'b':6}, amp_conv_class=example3, amp_conv_params={'a':2, 'b':22, 'magnitudes':['m']}) |
53 | | -DDS( 'dds4', pulseblaster_0.direct_outputs, 'dds 1') |
| 75 | +PineBlaster( |
| 76 | + name="pineblaster_0", |
| 77 | + trigger_device=ni_card_0, |
| 78 | + trigger_connection="port0/line15", |
| 79 | + usbport="COM7", |
| 80 | +) |
| 81 | +NI_PCI_6733( |
| 82 | + name="ni_card_1", |
| 83 | + parent_device=pineblaster_0.clockline, |
| 84 | + clock_terminal="ni_pcie_6733_0/PFI0", |
| 85 | + MAX_name="ni_pci_6733_0", |
| 86 | +) |
| 87 | + |
| 88 | +# Create the output/input channels on the above devices use the example1 conversion |
| 89 | +# class located in pythonlib/unitconversions/example.py with default paremeters |
| 90 | +AnalogOut( |
| 91 | + name="analog0", |
| 92 | + parent_device=ni_card_1, |
| 93 | + connection="ao0", |
| 94 | + unit_conversion_class=example1, |
| 95 | +) |
| 96 | + |
| 97 | +# same as above, but we are changing some parameters used in the conversion and |
| 98 | +# specifying a prefix to be used with units. You can now program in mA, uA, mGauss, |
| 99 | +# uGauss |
| 100 | +AnalogOut( |
| 101 | + name="analog1", |
| 102 | + parent_device=ni_card_1, |
| 103 | + connection="ao1", |
| 104 | + unit_conversion_class=example1, |
| 105 | + unit_conversion_parameters={"a": 5, "b": 1, "magnitudes": ["m", "u"]}, |
| 106 | +) |
| 107 | +AnalogOut(name="analog2", parent_device=ni_card_0, connection="ao2") |
| 108 | +AnalogOut(name="analog3", parent_device=ni_card_0, connection="ao3") |
| 109 | +AnalogIn(name="input1", parent_device=ni_card_0, connection="ai0") |
| 110 | +DigitalOut(name="do0", parent_device=ni_card_0, connection="port0/line2") |
| 111 | +Shutter( |
| 112 | + name="shutter1", parent_device=ni_card_0, connection="port0/line1", delay=(0, 0) |
| 113 | +) |
| 114 | +Shutter( |
| 115 | + name="shutter2", |
| 116 | + parent_device=pulseblaster_0.direct_outputs, |
| 117 | + connection="flag 2", |
| 118 | + delay=(0, 0), |
| 119 | +) |
| 120 | +DigitalOut( |
| 121 | + name="switch", parent_device=pulseblaster_0.direct_outputs, connection="flag 4" |
| 122 | +) |
| 123 | + |
| 124 | +DDS(name="dds1", parent_device=novatechdds9m_0, connection="channel 0") |
| 125 | +DDS(name="dds2", parent_device=novatechdds9m_0, connection="channel 1") |
| 126 | +StaticDDS(name="dds5", parent_device=novatechdds9m_0, connection="channel 2") |
| 127 | +# The next DDS is special because it has the frequency and amplitude calibrated using |
| 128 | +# example2 and example3 classes from pythonlib/unitconversions/example.py |
| 129 | +DDS( |
| 130 | + name="dds3", |
| 131 | + parent_device=pulseblaster_0.direct_outputs, |
| 132 | + connection="dds 0", |
| 133 | + freq_conv_class=example2, |
| 134 | + freq_conv_params={"a": 4, "b": 6}, |
| 135 | + amp_conv_class=example3, |
| 136 | + amp_conv_params={"a": 2, "b": 22, "magnitudes": ["m"]}, |
| 137 | +) |
| 138 | +DDS(name="dds4", parent_device=pulseblaster_0.direct_outputs, connection="dds 1") |
54 | 139 |
|
55 | 140 | # This sets up the inputs/counters/etc that will monitor |
56 | 141 | # The first paremeter is the name for the WaitMonitor device |
57 | | -# The second and third paremeters are the device and channel respectively that goes high when a wait begins and low when it ends. This output should be |
| 142 | +# The second and third paremeters are the device and channel respectively that goes |
| 143 | +# high when a wait begins and low when it ends. This output should be |
58 | 144 | # physically connected to a counter specified in the next two paremeters. |
59 | | -# The final two paremeters specify the device/channel that is to trigger the pseudoclock if the WAIT instruction hits the specified timeout. The output of |
60 | | -# this channel should be physicaly connect to the external trigger of the master pseudoclock. |
61 | | -WaitMonitor('wait_monitor', ni_card_0, 'port0/line0', ni_card_0, 'ctr0', ni_card_0, 'pfi1') |
| 145 | +# The final two paremeters specify the device/channel that is to trigger the |
| 146 | +# pseudoclock if the WAIT instruction hits the specified timeout. The output of |
| 147 | +# this channel should be physicaly connect to the external trigger of the master |
| 148 | +# pseudoclock. |
| 149 | +WaitMonitor( |
| 150 | + name="wait_monitor", |
| 151 | + parent_device=ni_card_0, |
| 152 | + connection="port0/line0", |
| 153 | + acquisition_device=ni_card_0, |
| 154 | + acquisition_connection="ctr0", |
| 155 | + timeout_device=ni_card_0, |
| 156 | + timeout_connection="pfi1", |
| 157 | +) |
62 | 158 |
|
63 | 159 | # A variable to define the acquisition rate used for the analog outputs below. |
64 | 160 | # This is just here to show you that you can use variables instead of typing in numbers! |
65 | | -# Furthermore, these variables could be defined within runmanager (rather than in the code like this one is) |
| 161 | +# Furthermore, these variables could be defined within runmanager (rather than in the |
| 162 | +# code like this one is) |
66 | 163 | # for easy manipulation via a graphical interface. |
67 | 164 | rate = 1e4 |
68 | 165 |
|
69 | 166 | # The time (in seconds) we wish the pineblaster pseudoclock to start after |
70 | 167 | # the master pseudoclock (the pulseblaster) |
71 | | -pineblaster_0.set_initial_trigger_time(1) |
| 168 | +pineblaster_0.set_initial_trigger_time(t=0.9) |
72 | 169 |
|
73 | 170 | # Start the experiment! |
74 | 171 | start() |
75 | 172 |
|
76 | 173 | # A variable to keep track of time |
77 | 174 | t = 0 |
78 | 175 |
|
79 | | -# Analog Acquisitions are acquired at the sample rate specified when the *device* is instantiated (eg NI_PCIE_6363() above) |
| 176 | +# Analog Acquisitions are acquired at the sample rate specified when the *device* is |
| 177 | +# instantiated (eg NI_PCIE_6363() above) |
80 | 178 | # Acquire an analog trace on this channel from t=0s to t=1s |
81 | | -input1.acquire('measurement1', 0, 1) |
| 179 | +input1.acquire(label='measurement1', start_time=0, end_time=1) |
82 | 180 | # Acquire an analog trace on this channel from t=3s to t=5s |
83 | | -input1.acquire('measurement2', 3, 5) |
| 181 | +input1.acquire(label='measurement2', start_time=3, end_time=5) |
84 | 182 | # Acquire an analog trace on this channel from t=7s to t=9s |
85 | | -input1.acquire('measurement3', 7, 9) |
| 183 | +input1.acquire(label='measurement3', start_time=7, end_time=9) |
86 | 184 |
|
87 | 185 | # Set some initial values (t=0) for DDS 1 |
88 | | -dds1.setamp(t, 0.5) |
89 | | -dds1.setfreq(t, 0.6) |
90 | | -dds1.setphase(t, 0.7) |
| 186 | +dds1.setamp(t=t, value=0.5) |
| 187 | +dds1.setfreq(t=t, value=0.6) |
| 188 | +dds1.setphase(t=t, value=0.7) |
91 | 189 |
|
92 | 190 | # Set some values for dds2 at t=1s. They will have value '0' before this |
93 | 191 | # time unless otherwise set |
94 | | -dds2.setamp(t+1, 0.9) |
95 | | -dds2.setfreq(t+1, 1.0) |
96 | | -dds2.setphase(t+1, 1.1) |
| 192 | +dds2.setamp(t=t + 1, value=0.9) |
| 193 | +dds2.setfreq(t=t + 1, value=1.0) |
| 194 | +dds2.setphase(t=t + 1, value=1.1) |
97 | 195 |
|
98 | 196 | # dds5 is a "static" DDS. This means its value can only be set once, and |
99 | 197 | # will be set just before the experiment begins |
100 | | -dds5.setfreq(90*MHz) |
101 | | -dds5.setamp(1) |
102 | | -dds5.setphase(0) |
| 198 | +dds5.setfreq(value=90 * MHz) |
| 199 | +dds5.setamp(value=1) |
| 200 | +dds5.setphase(value=0) |
103 | 201 |
|
104 | 202 | # Have the shutters start in the closed state (t=0) |
105 | | -shutter1.close(t) |
106 | | -shutter2.close(t) |
| 203 | +shutter1.close(t=t) |
| 204 | +shutter2.close(t=t) |
107 | 205 |
|
108 | | -# Analog0 is attached to ni_card_1, which is an NI-pci_6733 card (MAX name ni_pcie_6733_0) clocked by a pineblaster |
109 | | -# The pineblaster is being triggered to start by a pulseblaster, which introduces a delay into the start of output from the NI card |
110 | | -# This is all handled by labscript, and you still specify times from the beginning of the experiment (when the master pseudoclock is started) |
| 206 | +# Analog0 is attached to ni_card_1, which is an NI-pci_6733 card (MAX name |
| 207 | +# ni_pcie_6733_0) clocked by a pineblaster |
| 208 | +# The pineblaster is being triggered to start by a pulseblaster, which introduces |
| 209 | +# a delay into the start of output from the NI card |
| 210 | +# This is all handled by labscript, and you still specify times from the beginning of |
| 211 | +# the experiment (when the master pseudoclock is started) |
111 | 212 | # YOU DO NOT HAVE TO TAKE INTO ACCOUNT THE DELAY YOURSELF!! |
112 | | -# You do however need to make sure you do not command output from this device before the device has actually started. |
| 213 | +# You do however need to make sure you do not command output from this device before |
| 214 | +# the device has actually started. |
113 | 215 | # To do so, make sure no commands happen on this channel before analog0.t0 |
114 | 216 | # (this variable contains the delay time!) |
115 | | -analog0.constant(analog0.t0, 2) |
| 217 | +analog0.constant(t=analog0.t0, value=2) |
116 | 218 |
|
117 | 219 | # Set this channel to a constant value |
118 | 220 | # As this channel is clocked by the master pseudoclock, you can command |
119 | 221 | # output from t=0 |
120 | | -analog2.constant(t, 3) |
| 222 | +analog2.constant(t=t, value=3) |
121 | 223 |
|
122 | 224 | # Again, this must not start until analog1.t0 or later! |
123 | | -analog1.sine(analog1.t0, duration=6, amplitude=5, angfreq=2*pi, |
124 | | - phase=0, dc_offset=0.0, samplerate=rate) |
| 225 | +analog1.sine( |
| 226 | + t=analog1.t0, |
| 227 | + duration=6, |
| 228 | + amplitude=5, |
| 229 | + angfreq=2 * np.pi, |
| 230 | + phase=0, |
| 231 | + dc_offset=0.0, |
| 232 | + samplerate=rate, |
| 233 | +) |
125 | 234 |
|
126 | 235 | # Let's increment our time variable! |
127 | 236 | t += max(1, analog0.t0) |
128 | 237 |
|
129 | 238 | # Open the shutter, enable the DDS, ramp an analog output! |
130 | | -shutter2.open(t) |
131 | | -dds3.enable(t) |
132 | | -analog0.ramp(t, duration=2, initial=2, final=3, samplerate=rate) |
| 239 | +shutter2.open(t=t) |
| 240 | +dds3.enable(t=t) |
| 241 | +analog0.ramp(t=t, duration=2, initial=2, final=3, samplerate=rate) |
133 | 242 |
|
134 | 243 | # Take a picture |
135 | | -andor_ixon_0.expose('exposure_1', t, 'flat') |
136 | | -andor_ixon_0.expose('exposure_1', t+1, 'atoms') |
| 244 | +andor_ixon_0.expose(name='exposure_1', t=t, frametype='flat') |
| 245 | +andor_ixon_0.expose(name='exposure_1', t=t + 1, frametype='atoms') |
137 | 246 |
|
138 | 247 | # Do some more things at various times! |
139 | 248 | # (these are ignoring the t variable) |
140 | 249 | def my_ramp(t, *args, **kwargs): |
141 | 250 | lambda_func = functions.sine_ramp(*args, **kwargs) |
142 | 251 | return lambda_func(t) |
143 | | -analog2.sine_ramp(t=2.25, duration=3, initial=3, final=4, |
144 | | - samplerate=rate, truncation=0.7) |
| 252 | + |
| 253 | + |
| 254 | +analog2.sine_ramp( |
| 255 | + t=2.25, duration=3, initial=3, final=4, samplerate=rate, truncation=0.7 |
| 256 | +) |
145 | 257 | shutter1.open(t=5.89) |
146 | 258 | analog2.constant(t=5.9, value=5) |
147 | 259 | analog2.constant(t=7, value=4) |
148 | 260 | analog2.constant(t=8, value=5) |
149 | 261 |
|
| 262 | +# Incremenent t by 9 seconds |
| 263 | +t += 9 |
150 | 264 |
|
151 | | -t += 9 # set t=10 seconds |
152 | 265 | # Wait for an external trigger on the master pseudoclock |
153 | 266 | # Waits must be names |
154 | 267 | # The timeout defaults to 5s, unless otherwise specified. |
155 | 268 | # The timeout specifies how long to wait without seeing the external |
156 | 269 | # trigger before continuing the experiment |
157 | | -t += wait('my_first_wait', t=t, timeout=2) |
158 | | -# Waits take very little time as far as labscript is concerned. They only add on the retirggering time needed to start devices up and get them all in sync again. |
159 | | -# After a wait, labscript time (the t variable here) and execution time (when the hardware instructions are executed on the hardware) will not be the same |
| 270 | +t += wait(label='my_first_wait', t=t, timeout=2) |
| 271 | + |
| 272 | +# Waits take very little time as far as labscript is concerned. They only add on the |
| 273 | +# retirggering time needed to start devices up and get them all in sync again. |
| 274 | +# After a wait, labscript time (the t variable here) and execution time (when the |
| 275 | +# hardware instructions are executed on the hardware) will not be the same |
160 | 276 | # as the wait instruction may take anywhere from 0 to "timeout" seconds, |
161 | 277 | # and this number is only determined during execution time. |
162 | 278 |
|
163 | 279 | t += 1 |
164 | 280 | # Do something 1s after the wait! |
165 | | -switch.go_high(t) |
| 281 | +switch.go_high(t=t) |
166 | 282 |
|
167 | 283 | # Examples programming in different units as specified in the |
168 | 284 | # unitconversion classes passed as parameters to the channel definition |
169 | | -analog0.constant(t, value=5, units='A') |
170 | | -analog1.constant(t, value=1000, units='mGauss') |
171 | | -dds3.setfreq(t, value=50, units='detuned_MHz') |
172 | | -dds3.setamp(t, value=1.9, units='W') |
| 285 | +analog0.constant(t=t, value=5, units='A') |
| 286 | +analog1.constant(t=t, value=1000, units='mGauss') |
| 287 | +dds3.setfreq(t=t, value=50, units='detuned_MHz') |
| 288 | +dds3.setamp(t=t, value=1.9, units='W') |
| 289 | + |
| 290 | +# Hold values for 2 seconds |
173 | 291 | t += 2 |
174 | | -analog0.ramp(t, duration=1, initial=5, final=7, samplerate=rate, units='Gauss') |
175 | | -analog1.constant(t, value=3e6, units='uA') |
176 | | -dds3.setfreq(t, value=60, units='detuned_MHz') |
177 | | -dds3.setamp(t, value=500, units='mW') |
| 292 | + |
| 293 | +analog0.ramp(t=t, duration=1, initial=5, final=7, samplerate=rate, units='Gauss') |
| 294 | +analog1.constant(t=t, value=3e6, units='uA') |
| 295 | +dds3.setfreq(t=t, value=60, units='detuned_MHz') |
| 296 | +dds3.setamp(t=t, value=500, units='mW') |
| 297 | + |
| 298 | +# Hold values for 2 seconds |
178 | 299 | t += 2 |
| 300 | + |
179 | 301 | # Stop at t=15 seconds, note that because of the wait timeout, this might |
180 | 302 | # be as late as 17s (Plus a little bit of retriggering time) in execution |
181 | 303 | # time |
182 | | -stop(t) |
| 304 | +stop(t=t) |
0 commit comments