Completed
Push — pulsed_with_queued_connections ( 0b7aaa...175b78 )
by
unknown
04:14 queued 01:18
created

generate_ramsey()   B

Complexity

Conditions 6

Size

Total Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
dl 0
loc 79
rs 7.4071
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
# -*- coding: utf-8 -*-
2
3
"""
4
This file contains the Qudi Predefined Methods for sequence generator
5
6
Qudi is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
10
11
Qudi is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with Qudi. If not, see <http://www.gnu.org/licenses/>.
18
19
Copyright (c) the Qudi Developers. See the COPYRIGHT.txt file at the
20
top-level directory of this distribution and at <https://github.com/Ulm-IQO/qudi/>
21
"""
22
23
24
from logic.pulse_objects import PulseBlockElement
25
from logic.pulse_objects import PulseBlock
26
from logic.pulse_objects import PulseBlockEnsemble
27
from logic.pulse_objects import PulseSequence
0 ignored issues
show
Unused Code introduced by
Unused PulseSequence imported from logic.pulse_objects
Loading history...
28
import numpy as np
29
30
31
"""
32
General Pulse Creation Procedure:
33
=================================
34
- Create at first each PulseBlockElement object
35
- add all PulseBlockElement object to a list and combine them to a
36
  PulseBlock object.
37
- Create all needed PulseBlock object with that idea, that means
38
  PulseBlockElement objects which are grouped to PulseBlock objects.
39
- Create from the PulseBlock objects a PulseBlockEnsemble object.
40
- If needed and if possible, combine the created PulseBlockEnsemble objects
41
  to the highest instance together in a PulseSequence object.
42
"""
43
44
45
def generate_laser_on(self, name='Laser_On', length=3.0e-6, amp=1.0):
46
    """ Generates Laser on.
47
48
    @param str name: Name of the PulseBlockEnsemble
49
    @param float length: laser duration in seconds
50
    @param float amp: In case of analogue laser channel this value will be the laser on voltage.
51
52
    @return object: the generated PulseBlockEnsemble object.
53
    """
54
    # create the laser element
55
    laser_element = self._get_laser_element(length, amp_V=amp)
56
    # Create the element list
57
    element_list = [laser_element]
58
    # create the PulseBlock object.
59
    block = PulseBlock(name, element_list)
60
    # put block in a list with repetitions
61
    block_list = [(block, 0)]
62
    # create ensemble out of the block(s)
63
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=False)
64
    # save ensemble
65
    self.save_ensemble(name, block_ensemble)
66
    return block_ensemble
67
68
69
def generate_laser_mw_on(self, name='Laser_MW_On', length=3.0e-6, laser_amp=1.0, mw_channel='a_ch1',
70
                         mw_freq=100.0e6, mw_amp=1.0):
71
    """ General generation method for laser on and microwave on generation.
72
73
    @param string name: Name of the PulseBlockEnsemble to be generated
74
    @param float length: Length of the PulseBlockEnsemble in seconds
75
    @param float laser_amp: In case of analog laser channel this value will be the laser on voltage.
76
    @param string mw_channel: The pulser channel controlling the MW. If set to 'd_chX' this will be
77
                              interpreted as trigger for an external microwave source. If set to
78
                              'a_chX' the pulser (AWG) will act as microwave source.
79
    @param float mw_freq: MW frequency in case of analogue MW channel in Hz
80
    @param float mw_amp: MW amplitude in case of analogue MW channel
81
82
    @return object: the generated PulseBlockEnsemble object.
83
    """
84
    # sanity checks for input parameters
85
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel)
86
    if err_code != 0:
87
        return
88
89
    laser_mw_element = self._get_mw_laser_element(length, 0.0, mw_channel, False,
90
                                                  laser_amp=laser_amp, mw_amp=mw_amp,
91
                                                  mw_freq=mw_freq)
92
    # Create the element list.
93
    element_list = [laser_mw_element]
94
    # create the PulseBlock object.
95
    block = PulseBlock(name, element_list)
96
    # put block in a list with repetitions
97
    block_list = [(block, 0)]
98
    # create ensemble out of the block(s)
99
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=False)
100
    # save ensemble
101
    self.save_ensemble(name, block_ensemble)
102
    return block_ensemble
103
104
105
def generate_idle(self, name='Idle', length=3.0e-6):
106
    """ Generate just a simple idle ensemble.
107
108
    @param str name: Name of the PulseBlockEnsemble to be generated
109
    @param float length: Length of the PulseBlockEnsemble in seconds
110
111
    @return object: the generated PulseBlockEnsemble object.
112
    """
113
    # generate idle element
114
    idle_element = self._get_idle_element(length, 0.0, False)
115
    # Create the element list.
116
    element_list = [idle_element]
117
    # create the PulseBlock object.
118
    block = PulseBlock(name, element_list)
119
    # put block in a list with repetitions
120
    block_list = [(block, 0)]
121
    # create ensemble out of the block(s)
122
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=False)
123
    # save ensemble
124
    self.save_ensemble(name, block_ensemble)
125
    return block_ensemble
126
127
128
def generate_rabi(self, name='Rabi', tau_start=10.0e-9, tau_step=10.0e-9, number_of_taus=50,
129
                  mw_freq=2870.0e6, mw_amp=1.0, mw_channel='a_ch1', laser_length=3.0e-6,
130
                  channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6, gate_count_channel='',
131
                  seq_trig_channel=''):
132
    """
133
134
    """
135
    # Sanity checks
136
    if gate_count_channel == '':
137
        gate_count_channel = None
138
    if seq_trig_channel == '':
139
        seq_trig_channel = None
140
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
141
                                              gate_count_channel=gate_count_channel,
142
                                              seq_trig_channel=seq_trig_channel)
143
    if err_code != 0:
144
        return
145
146
    # get MW element
147
    mw_element = self._get_mw_element(tau_start, tau_step, mw_channel, True, mw_amp, mw_freq, 0.0)
148
    # get waiting element
149
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
150
    # get laser and delay element
151
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
152
                                                           channel_amp, gate_count_channel)
153
    if seq_trig_channel is not None:
154
        # get sequence trigger element
155
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
156
        # Create its own block out of the element
157
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
158
        # save block
159
        self.save_block('seq_trigger', seq_block)
160
161
    # Create element list for Rabi PulseBlock
162
    element_list = [mw_element, laser_element, delay_element, waiting_element]
163
    # Create PulseBlock object
164
    rabi_block = PulseBlock(name, element_list)
165
    # save block
166
    self.save_block(name, rabi_block)
167
168
    # Create Block list with repetitions and sequence trigger if needed.
169
    # remember number_of_taus=0 also counts as first round.
170
    block_list = [(rabi_block, number_of_taus-1)]
171
    if seq_trig_channel is not None:
172
        block_list.append((seq_block, 0))
173
174
    # create ensemble out of the block(s)
175
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=False)
176
    # save ensemble
177
    self.save_ensemble(name, block_ensemble)
178
    return block_ensemble
179
180
181
def generate_pulsedodmr(self, name='PulsedODMR', pi_length=1.0e-6, mw_freq_start=2870.0e6,
182
                        mw_freq_incr=0.2e6, num_of_points=50, mw_amp=1.0, mw_channel='a_ch1',
183
                        laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6,
184
                        seq_trig_channel='', gate_count_channel=''):
185
    """
186
187
    """
188
    # Sanity checks
189
    if gate_count_channel == '':
190
        gate_count_channel = None
191
    if seq_trig_channel == '':
192
        seq_trig_channel = None
193
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
194
                                              gate_count_channel=gate_count_channel,
195
                                              seq_trig_channel=seq_trig_channel)
196
    if err_code != 0:
197
        return
198
199
    # get waiting element
200
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
201
    # get laser and delay element
202
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
203
                                                           channel_amp, gate_count_channel)
204
    if seq_trig_channel is not None:
205
        # get sequence trigger element
206
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
207
        # Create its own block out of the element
208
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
209
        # save block
210
        self.save_block('seq_trigger', seq_block)
211
212
    # Create frequency list array
213
    freq_array = mw_freq_start + np.arange(num_of_points) * mw_freq_incr
214
215
    # Create element list for PulsedODMR PulseBlock
216
    element_list = []
217
    for mw_freq in freq_array:
218
        mw_element = self._get_mw_element(pi_length, 0.0, mw_channel, False, mw_amp, mw_freq, 0.0)
219
        element_list.append(mw_element)
220
        element_list.append(laser_element)
221
        element_list.append(delay_element)
222
        element_list.append(waiting_element)
223
    # Create PulseBlock object
224
    pulsedodmr_block = PulseBlock(name, element_list)
225
    # save block
226
    self.save_block(name, pulsedodmr_block)
227
228
    # Create Block list with repetitions and sequence trigger if needed.
229
    # remember number_of_taus=0 also counts as first round.
230
    block_list = [(pulsedodmr_block, 0)]
231
    if seq_trig_channel is not None:
232
        block_list.append((seq_block, 0))
233
234
    # create ensemble out of the block(s)
235
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=False)
236
    # add metadata to ensemble object
237
    block_ensemble.measurement_ticks_list = freq_array
238
    # save ensemble
239
    self.save_ensemble(name, block_ensemble)
240
    return block_ensemble
241
242
243
def generate_ramsey(self, name='Ramsey', rabi_period=1.0e-6, mw_freq=2870.0e6, mw_amp=0.1,
244
                    tau_start=1.0e-6, tau_incr=1.0e-6, num_of_points=50, mw_channel='a_ch1',
245
                    laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6,
246
                    seq_trig_channel='', gate_count_channel=''):
247
    """
248
249
    """
250
    # Sanity checks
251
    if gate_count_channel == '':
252
        gate_count_channel = None
253
    if seq_trig_channel == '':
254
        seq_trig_channel = None
255
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
256
                                              gate_count_channel=gate_count_channel,
257
                                              seq_trig_channel=seq_trig_channel)
258
    if err_code != 0:
259
        return
260
261
    # get tau array for measurement ticks
262
    tau_array = tau_start + np.arange(num_of_points) * tau_incr
263
    # calculate "true" tau start value due to finite length of pi/pihalf pulses
264
    real_tau_start = tau_start - rabi_period / 4
265
266
    # get waiting element
267
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
268
    # get laser and delay element
269
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
270
                                                           channel_amp, gate_count_channel)
271
    # get pihalf element
272
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
273
                                          0.0)
274
    # get 3pihalf element (same length as pihalf but with 270 deg phase)
275
    pi3half_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
276
                                           270.0)
277
    # get tau element
278
    tau_element = self._get_idle_element(real_tau_start, tau_incr, True)
279
280
    if seq_trig_channel is not None:
281
        # get sequence trigger element
282
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
283
        # Create its own block out of the element
284
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
285
        # save block
286
        self.save_block('seq_trigger', seq_block)
287
288
    # Create element list for alternating Ramsey PulseBlock
289
    element_list = []
290
    element_list.append(pihalf_element)
291
    element_list.append(tau_element)
292
    element_list.append(pihalf_element)
293
    element_list.append(laser_element)
294
    element_list.append(delay_element)
295
    element_list.append(waiting_element)
296
297
    element_list.append(pihalf_element)
298
    element_list.append(tau_element)
299
    element_list.append(pi3half_element)
300
    element_list.append(laser_element)
301
    element_list.append(delay_element)
302
    element_list.append(waiting_element)
303
304
    # Create PulseBlock object
305
    ramsey_block = PulseBlock(name, element_list)
306
    # save block
307
    self.save_block(name, ramsey_block)
308
309
    # Create Block list with repetitions and sequence trigger if needed.
310
    # remember number_of_taus=0 also counts as first round.
311
    block_list = [(ramsey_block, num_of_points - 1)]
312
    if seq_trig_channel is not None:
313
        block_list.append((seq_block, 0))
314
315
    # create ensemble out of the block(s)
316
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
317
    # add metadata to ensemble object
318
    block_ensemble.measurement_ticks_list = tau_array
319
    # save ensemble
320
    self.save_ensemble(name, block_ensemble)
321
    return block_ensemble
322
323
324
def generate_hahnecho(self, name='HahnEcho', rabi_period=1.0e-6, mw_freq=2870.0e6, mw_amp=0.1,
325
                      tau_start=1.0e-6, tau_incr=1.0e-6, num_of_points=50, mw_channel='a_ch1',
326
                      laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6,
327
                      seq_trig_channel='', gate_count_channel=''):
328
    """
329
330
    """
331
    # Sanity checks
332
    if gate_count_channel == '':
333
        gate_count_channel = None
334
    if seq_trig_channel == '':
335
        seq_trig_channel = None
336
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
337
                                              gate_count_channel=gate_count_channel,
338
                                              seq_trig_channel=seq_trig_channel)
339
    if err_code != 0:
340
        return
341
342
    # get tau array for measurement ticks
343
    tau_array = tau_start + np.arange(num_of_points) * tau_incr
344
    # calculate "true" tau start value due to finite length of pi/pihalf pulses
345
    real_tau_start = tau_start - 3 * rabi_period / 8
346
347
    # get waiting element
348
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
349
    # get laser and delay element
350
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
351
                                                           channel_amp, gate_count_channel)
352
    # get pihalf element
353
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
354
                                          0.0)
355
    # get 3pihalf element (same length as pihalf but with 270 deg phase)
356
    pi3half_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
357
                                           270.0)
358
    # get pi element
359
    pi_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq, 0.0)
360
    # get tau element
361
    tau_element = self._get_idle_element(real_tau_start, tau_incr, False)
362
363
    if seq_trig_channel is not None:
364
        # get sequence trigger element
365
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
366
        # Create its own block out of the element
367
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
368
        # save block
369
        self.save_block('seq_trigger', seq_block)
370
371
    # Create element list for alternating Hahn Echo PulseBlock
372
    element_list = []
373
    element_list.append(pihalf_element)
374
    element_list.append(tau_element)
375
    element_list.append(pi_element)
376
    element_list.append(tau_element)
377
    element_list.append(pihalf_element)
378
    element_list.append(laser_element)
379
    element_list.append(delay_element)
380
    element_list.append(waiting_element)
381
382
    element_list.append(pihalf_element)
383
    element_list.append(tau_element)
384
    element_list.append(pi_element)
385
    element_list.append(tau_element)
386
    element_list.append(pi3half_element)
387
    element_list.append(laser_element)
388
    element_list.append(delay_element)
389
    element_list.append(waiting_element)
390
391
    # Create PulseBlock object
392
    hahn_block = PulseBlock(name, element_list)
393
    # save block
394
    self.save_block(name, hahn_block)
395
396
    # Create Block list with repetitions and sequence trigger if needed.
397
    # remember number_of_taus=0 also counts as first round.
398
    block_list = [(hahn_block, num_of_points - 1)]
399
    if seq_trig_channel is not None:
400
        block_list.append((seq_block, 0))
401
402
    # create ensemble out of the block(s)
403
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
404
    # add metadata to ensemble object
405
    block_ensemble.measurement_ticks_list = tau_array
406
    # save ensemble
407
    self.save_ensemble(name, block_ensemble)
408
    return block_ensemble
409
410
411 View Code Duplication
def generate_HHamp(self, name='HHamp', rabi_period=1.0e-6, spinlock_length=20e-6, mw_freq=2870.0e6,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
412
                   pulse_amp=0.5, start_amp=0.05, incr_amp=0.01, num_of_points=50,
413
                   mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6,
414
                   wait_time=1.0e-6, seq_trig_channel='', gate_count_channel=''):
415
    """
416
417
    """
418
    # Sanity checks
419
    if gate_count_channel == '':
420
        gate_count_channel = None
421
    if seq_trig_channel == '':
422
        seq_trig_channel = None
423
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
424
                                              gate_count_channel=gate_count_channel,
425
                                              seq_trig_channel=seq_trig_channel)
426
    if err_code != 0:
427
        return
428
429
    # get waiting element
430
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
431
    # get laser and delay element
432
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
433
                                                           channel_amp, gate_count_channel)
434
    # get pihalf element
435
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
436
                                          mw_freq, 0.0)
437
    # get 3pihalf element
438
    pi3half_element = self._get_mw_element(3 * rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
439
                                           mw_freq, 0.0)
440
441
    if seq_trig_channel is not None:
442
        # get sequence trigger element
443
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
444
        # Create its own block out of the element
445
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
446
        # save block
447
        self.save_block('seq_trigger', seq_block)
448
449
    # Create amplitude list array
450
    amp_array = start_amp + np.arange(num_of_points) * incr_amp
451
452
    # Create element list for HHamp PulseBlock
453
    element_list = []
454
    for sl_amp in amp_array:
455
        sl_element = self._get_mw_element(spinlock_length, 0.0, mw_channel, False, sl_amp, mw_freq,
456
                                          0.0)
457
        # actual alternating HH-amp sequence
458
        element_list.append(pihalf_element)
459
        element_list.append(sl_element)
460
        element_list.append(pihalf_element)
461
        element_list.append(laser_element)
462
        element_list.append(delay_element)
463
        element_list.append(waiting_element)
464
465
        element_list.append(pi3half_element)
466
        element_list.append(sl_element)
467
        element_list.append(pi3half_element)
468
        element_list.append(laser_element)
469
        element_list.append(delay_element)
470
        element_list.append(waiting_element)
471
472
    # Create PulseBlock object
473
    hhamp_block = PulseBlock(name, element_list)
474
    # save block
475
    self.save_block(name, hhamp_block)
476
477
    # Create Block list with repetitions and sequence trigger if needed.
478
    # remember number_of_taus=0 also counts as first round.
479
    block_list = [(hhamp_block, 0)]
480
    if seq_trig_channel is not None:
481
        block_list.append((seq_block, 0))
482
483
    # create ensemble out of the block(s)
484
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
485
    # add metadata to ensemble object
486
    block_ensemble.measurement_ticks_list = amp_array
487
    # save ensemble
488
    self.save_ensemble(name, block_ensemble)
489
    return block_ensemble
490
491 View Code Duplication
def generate_HHtau(self, name='HHtau', rabi_period=1.0e-6, spinlock_amp=0.1, mw_freq=2870.0e6,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
492
                   pulse_amp=0.5, start_tau=0.05, incr_tau=0.01, num_of_points=50,
493
                   mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6,
494
                   wait_time=1.0e-6, seq_trig_channel='', gate_count_channel=''):
495
    """
496
497
    """
498
    # Sanity checks
499
    if gate_count_channel == '':
500
        gate_count_channel = None
501
    if seq_trig_channel == '':
502
        seq_trig_channel = None
503
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
504
                                              gate_count_channel=gate_count_channel,
505
                                              seq_trig_channel=seq_trig_channel)
506
    if err_code != 0:
507
        return
508
509
    # get waiting element
510
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
511
    # get laser and delay element
512
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
513
                                                           channel_amp, gate_count_channel)
514
    # get pihalf element
515
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
516
                                          mw_freq, 0.0)
517
    # get 3pihalf element
518
    pi3half_element = self._get_mw_element(3 * rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
519
                                           mw_freq, 0.0)
520
    # get spinlock element
521
    sl_element = self._get_mw_element(start_tau, incr_tau, mw_channel, True, spinlock_amp, mw_freq,
522
                                      0.0)
523
524
    if seq_trig_channel is not None:
525
        # get sequence trigger element
526
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
527
        # Create its own block out of the element
528
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
529
        # save block
530
        self.save_block('seq_trigger', seq_block)
531
532
    # Create element list for HHamp PulseBlock
533
    element_list = []
534
    # actual alternating HH-amp sequence
535
    element_list.append(pihalf_element)
536
    element_list.append(sl_element)
537
    element_list.append(pihalf_element)
538
    element_list.append(laser_element)
539
    element_list.append(delay_element)
540
    element_list.append(waiting_element)
541
542
    element_list.append(pi3half_element)
543
    element_list.append(sl_element)
544
    element_list.append(pi3half_element)
545
    element_list.append(laser_element)
546
    element_list.append(delay_element)
547
    element_list.append(waiting_element)
548
549
    # Create PulseBlock object
550
    hhtau_block = PulseBlock(name, element_list)
551
    # save block
552
    self.save_block(name, hhtau_block)
553
554
    # Create Block list with repetitions and sequence trigger if needed.
555
    # remember number_of_taus=0 also counts as first round.
556
    block_list = [(hhtau_block, num_of_points-1)]
557
    if seq_trig_channel is not None:
558
        block_list.append((seq_block, 0))
559
560
    # create ensemble out of the block(s)
561
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
562
    # save ensemble
563
    self.save_ensemble(name, block_ensemble)
564
    return block_ensemble
565
566
567
def generate_HHpol(self, name='HHpol', rabi_period=1.0e-6, spinlock_length=20.0e-6,
568
                   spinlock_amp=0.1, mw_freq=2870.0e6, pulse_amp=0.5, polarization_steps=50,
569
                   mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6,
570
                   wait_time=1.0e-6, seq_trig_channel='', gate_count_channel=''):
571
    """
572
573
    """
574
    # Sanity checks
575
    if gate_count_channel == '':
576
        gate_count_channel = None
577
    if seq_trig_channel == '':
578
        seq_trig_channel = None
579
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
580
                                              gate_count_channel=gate_count_channel,
581
                                              seq_trig_channel=seq_trig_channel)
582
    if err_code != 0:
583
        return
584
585
    # get waiting element
586
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
587
    # get laser and delay element
588
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
589
                                                           channel_amp, gate_count_channel)
590
    # get pihalf element
591
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
592
                                          mw_freq, 0.0)
593
    # get 3pihalf element
594
    pi3half_element = self._get_mw_element(3 * rabi_period / 4, 0.0, mw_channel, False, pulse_amp,
595
                                           mw_freq, 0.0)
596
    # get spinlock element
597
    sl_element = self._get_mw_element(spinlock_length, 0.0, mw_channel, False, spinlock_amp,
598
                                      mw_freq, 0.0)
599
600
    if seq_trig_channel is not None:
601
        # get sequence trigger element
602
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
603
        # Create its own block out of the element
604
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
605
        # save block
606
        self.save_block('seq_trigger', seq_block)
607
608
    # create the pulse block for "up"-polarization
609
    element_list = []
610
    # actual HH-pol sequence
611
    element_list.append(pihalf_element)
612
    element_list.append(sl_element)
613
    element_list.append(pihalf_element)
614
    element_list.append(laser_element)
615
    element_list.append(delay_element)
616
    element_list.append(waiting_element)
617
618
    HHpolup_block = PulseBlock(name + '_up', element_list)
619
    self.save_block(name + '_up', HHpolup_block)
620
621
    # create the pulse block for "down"-polarization
622
    element_list = []
623
    # actual HH-pol sequence
624
    element_list.append(pi3half_element)
625
    element_list.append(sl_element)
626
    element_list.append(pi3half_element)
627
    element_list.append(laser_element)
628
    element_list.append(delay_element)
629
    element_list.append(waiting_element)
630
631
    HHpoldown_block = PulseBlock(name + '_down', element_list)
632
    self.save_block(name + '_down', HHpoldown_block)
633
634
    # Create Block list with repetitions and sequence trigger if needed
635
    # remember number_of_taus=0 also counts as first round
636
    block_list = [(HHpolup_block, polarization_steps - 1),
637
                  (HHpoldown_block, polarization_steps - 1)]
638
    if seq_trig_channel:
639
        block_list.append((seq_block, 0))
640
641
    # create ensemble out of the block(s)
642
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
643
    # add metadata to ensemble object
644
    block_ensemble.measurement_ticks_list = np.arange(1, 2 * polarization_steps + 1)
645
    # save ensemble
646
    self.save_ensemble(name, block_ensemble)
647
    return block_ensemble
648
649
650
def generate_xy8_tau(self, name='XY8_tau', rabi_period=1.0e-6, mw_freq=2870.0e6, mw_amp=0.1,
651
                     start_tau=0.5e-6, incr_tau=0.01e-6, num_of_points=50, xy8_order=4,
652
                     mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6,
653
                     wait_time=1.0e-6, seq_trig_channel='', gate_count_channel=''):
654
    """
655
656
    """
657
    # Sanity checks
658
    if gate_count_channel == '':
659
        gate_count_channel = None
660
    if seq_trig_channel == '':
661
        seq_trig_channel = None
662
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
663
                                              gate_count_channel=gate_count_channel,
664
                                              seq_trig_channel=seq_trig_channel)
665
    if err_code != 0:
666
        return
667
668
    # get tau array for measurement ticks
669
    tau_array = start_tau + np.arange(num_of_points) * incr_tau
670
    # calculate "real" start length of the waiting times (tau and tauhalf)
671
    real_start_tau = start_tau - rabi_period / 2
672
    real_start_tauhalf = start_tau / 2 - 3 * rabi_period / 8
673
    if real_start_tau < 0.0 or real_start_tauhalf < 0.0:
674
        self.log.error('XY8 generation failed! Rabi period of {0:.3e} s is too long for start tau '
675
                       'of {1:.3e} s.'.format(rabi_period, start_tau))
676
        return
677
678
    # get waiting element
679
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
680
    # get laser and delay element
681
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
682
                                                           channel_amp, gate_count_channel)
683
    # get pihalf element
684
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
685
                                          0.0)
686
    # get 3pihalf element (same length but 270 deg phase due to the correction of tau length)
687
    pi3half_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
688
                                           270.0)
689
    # get pi elements
690
    pix_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq,
691
                                       0.0)
692
    piy_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq,
693
                                       90.0)
694
    # get tauhalf element
695
    tauhalf_element = self._get_idle_element(real_start_tauhalf, incr_tau / 2, False)
696
    # get tau element
697
    tau_element = self._get_idle_element(real_start_tau, incr_tau, False)
698
699
    if seq_trig_channel is not None:
700
        # get sequence trigger element
701
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
702
        # Create its own block out of the element
703
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
704
        # save block
705
        self.save_block('seq_trigger', seq_block)
706
707
    # create XY8-N block element list
708
    xy8_elem_list = []
709
    # actual XY8-N sequence
710
    xy8_elem_list.append(pihalf_element)
711
    xy8_elem_list.append(tauhalf_element)
712
    for n in range(xy8_order):
713
        xy8_elem_list.append(pix_element)
714
        xy8_elem_list.append(tau_element)
715
        xy8_elem_list.append(piy_element)
716
        xy8_elem_list.append(tau_element)
717
        xy8_elem_list.append(pix_element)
718
        xy8_elem_list.append(tau_element)
719
        xy8_elem_list.append(piy_element)
720
        xy8_elem_list.append(tau_element)
721
        xy8_elem_list.append(piy_element)
722
        xy8_elem_list.append(tau_element)
723
        xy8_elem_list.append(pix_element)
724
        xy8_elem_list.append(tau_element)
725
        xy8_elem_list.append(piy_element)
726
        xy8_elem_list.append(tau_element)
727
        xy8_elem_list.append(pix_element)
728
        if n != xy8_order-1:
729
            xy8_elem_list.append(tau_element)
730
    xy8_elem_list.append(tauhalf_element)
731
    xy8_elem_list.append(pihalf_element)
732
    xy8_elem_list.append(laser_element)
733
    xy8_elem_list.append(delay_element)
734
    xy8_elem_list.append(waiting_element)
735
736
    xy8_elem_list.append(pihalf_element)
737
    xy8_elem_list.append(tauhalf_element)
738
    for n in range(xy8_order):
739
        xy8_elem_list.append(pix_element)
740
        xy8_elem_list.append(tau_element)
741
        xy8_elem_list.append(piy_element)
742
        xy8_elem_list.append(tau_element)
743
        xy8_elem_list.append(pix_element)
744
        xy8_elem_list.append(tau_element)
745
        xy8_elem_list.append(piy_element)
746
        xy8_elem_list.append(tau_element)
747
        xy8_elem_list.append(piy_element)
748
        xy8_elem_list.append(tau_element)
749
        xy8_elem_list.append(pix_element)
750
        xy8_elem_list.append(tau_element)
751
        xy8_elem_list.append(piy_element)
752
        xy8_elem_list.append(tau_element)
753
        xy8_elem_list.append(pix_element)
754
        if n != xy8_order - 1:
755
            xy8_elem_list.append(tau_element)
756
    xy8_elem_list.append(tauhalf_element)
757
    xy8_elem_list.append(pi3half_element)
758
    xy8_elem_list.append(laser_element)
759
    xy8_elem_list.append(delay_element)
760
    xy8_elem_list.append(waiting_element)
761
762
    # create XY8-N block object
763
    xy8_block = PulseBlock(name, xy8_elem_list)
764
    self.save_block(name, xy8_block)
765
766
    # create block list and ensemble object
767
    block_list = [(xy8_block, num_of_points - 1)]
768
    if seq_trig_channel is not None:
769
        block_list.append((seq_block, 0))
770
771
    # create ensemble out of the block(s)
772
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
773
    # add metadata to ensemble object
774
    block_ensemble.measurement_ticks_list = tau_array
775
    # save ensemble
776
    self.save_ensemble(name, block_ensemble)
777
    return block_ensemble
778
779
780
def generate_xy8_freq(self, name='XY8_freq', rabi_period=1.0e-6, mw_freq=2870.0e6, mw_amp=0.1,
781
                      start_freq=0.1e6, incr_freq=0.01e6, num_of_points=50, xy8_order=4,
782
                      mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6,
783
                      wait_time=1.0e-6, seq_trig_channel='', gate_count_channel=''):
784
    """
785
786
    """
787
    # Sanity checks
788
    if gate_count_channel == '':
789
        gate_count_channel = None
790
    if seq_trig_channel == '':
791
        seq_trig_channel = None
792
    err_code = self._do_channel_sanity_checks(mw_channel=mw_channel,
793
                                              gate_count_channel=gate_count_channel,
794
                                              seq_trig_channel=seq_trig_channel)
795
    if err_code != 0:
796
        return
797
798
    # get frequency array for measurement ticks
799
    freq_array = start_freq + np.arange(num_of_points) * incr_freq
800
    # get tau array from freq array
801
    tau_array = 1 / (2 * freq_array)
802
    # calculate "real" tau and tauhalf arrays
803
    real_tau_array = tau_array - rabi_period / 2
804
    real_tauhalf_array = tau_array / 2 - 3 * rabi_period / 8
805
    if True in (real_tau_array < 0.0) or True in (real_tauhalf_array < 0.0):
806
        self.log.error('XY8 generation failed! Rabi period of {0:.3e} s is too long for start tau '
807
                       'of {1:.3e} s.'.format(rabi_period, real_tau_array[0]))
808
        return
809
810
    # get waiting element
811
    waiting_element = self._get_idle_element(wait_time, 0.0, False)
812
    # get laser and delay element
813
    laser_element, delay_element = self._get_laser_element(laser_length, 0.0, False, delay_length,
814
                                                           channel_amp, gate_count_channel)
815
    # get pihalf element
816
    pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
817
                                          0.0)
818
    # get 3pihalf element (same length but 270 deg phase due to the correction of tau length)
819
    pi3half_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq,
820
                                           270.0)
821
    # get pi elements
822
    pix_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq,
823
                                       0.0)
824
    piy_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq,
825
                                       90.0)
826
827
    if seq_trig_channel is not None:
828
        # get sequence trigger element
829
        seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp)
830
        # Create its own block out of the element
831
        seq_block = PulseBlock('seq_trigger', [seqtrig_element])
832
        # save block
833
        self.save_block('seq_trigger', seq_block)
834
835
    # create XY8-N block element list
836
    xy8_elem_list = []
837
    # actual XY8-N sequence
838
    for i in range(num_of_points):
839
        # get tau element
840
        tau_element = self._get_idle_element(real_tau_array[i], 0.0, False)
841
        # get tauhalf element
842
        tauhalf_element = self._get_idle_element(real_tauhalf_array[i], 0.0, False)
843
844
        xy8_elem_list.append(pihalf_element)
845
        xy8_elem_list.append(tauhalf_element)
846
        for n in range(xy8_order):
847
            xy8_elem_list.append(pix_element)
848
            xy8_elem_list.append(tau_element)
849
            xy8_elem_list.append(piy_element)
850
            xy8_elem_list.append(tau_element)
851
            xy8_elem_list.append(pix_element)
852
            xy8_elem_list.append(tau_element)
853
            xy8_elem_list.append(piy_element)
854
            xy8_elem_list.append(tau_element)
855
            xy8_elem_list.append(piy_element)
856
            xy8_elem_list.append(tau_element)
857
            xy8_elem_list.append(pix_element)
858
            xy8_elem_list.append(tau_element)
859
            xy8_elem_list.append(piy_element)
860
            xy8_elem_list.append(tau_element)
861
            xy8_elem_list.append(pix_element)
862
            if n != xy8_order-1:
863
                xy8_elem_list.append(tau_element)
864
        xy8_elem_list.append(tauhalf_element)
865
        xy8_elem_list.append(pihalf_element)
866
        xy8_elem_list.append(laser_element)
867
        xy8_elem_list.append(delay_element)
868
        xy8_elem_list.append(waiting_element)
869
870
        xy8_elem_list.append(pihalf_element)
871
        xy8_elem_list.append(tauhalf_element)
872
        for n in range(xy8_order):
873
            xy8_elem_list.append(pix_element)
874
            xy8_elem_list.append(tau_element)
875
            xy8_elem_list.append(piy_element)
876
            xy8_elem_list.append(tau_element)
877
            xy8_elem_list.append(pix_element)
878
            xy8_elem_list.append(tau_element)
879
            xy8_elem_list.append(piy_element)
880
            xy8_elem_list.append(tau_element)
881
            xy8_elem_list.append(piy_element)
882
            xy8_elem_list.append(tau_element)
883
            xy8_elem_list.append(pix_element)
884
            xy8_elem_list.append(tau_element)
885
            xy8_elem_list.append(piy_element)
886
            xy8_elem_list.append(tau_element)
887
            xy8_elem_list.append(pix_element)
888
            if n != xy8_order - 1:
889
                xy8_elem_list.append(tau_element)
890
        xy8_elem_list.append(tauhalf_element)
891
        xy8_elem_list.append(pi3half_element)
892
        xy8_elem_list.append(laser_element)
893
        xy8_elem_list.append(delay_element)
894
        xy8_elem_list.append(waiting_element)
895
896
    # create XY8-N block object
897
    xy8_block = PulseBlock(name, xy8_elem_list)
898
    self.save_block(name, xy8_block)
899
900
    # create block list and ensemble object
901
    block_list = [(xy8_block, num_of_points - 1)]
902
    if seq_trig_channel is not None:
903
        block_list.append((seq_block, 0))
904
905
    # create ensemble out of the block(s)
906
    block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True)
907
    # add metadata to ensemble object
908
    block_ensemble.measurement_ticks_list = freq_array
909
    # save ensemble
910
    self.save_ensemble(name, block_ensemble)
911
    return block_ensemble
912
913
914
####################################################################################################
915
#                                   Helper methods                                              ####
916
####################################################################################################
917
def _get_channel_lists(self):
918
    """
919
    @return: two lists with the names of digital and analog channels
920
    """
921
    # split digital and analogue channels
922
    digital_channels = [chnl for chnl in self.activation_config if 'd_ch' in chnl]
923
    analog_channels = [chnl for chnl in self.activation_config if 'a_ch' in chnl]
924
    return digital_channels, analog_channels
925
926
927
def _get_idle_element(self, length, increment, use_as_tick):
928
    """
929
    Creates an idle pulse PulseBlockElement
930
931
    @param float length: idle duration in seconds
932
    @param float increment: idle duration increment in seconds
933
    @param bool use_as_tick: use as tick flag of the PulseBlockElement
934
935
    @return: PulseBlockElement, the generated idle element
936
    """
937
    # input params for MW element generation
938
    idle_params = [{}] * self.analog_channels
939
    idle_digital = [False] * self.digital_channels
940
    idle_function = ['Idle'] * self.analog_channels
941
942
    # Create idle element
943
    idle_element = PulseBlockElement(init_length_s=length, increment_s=increment,
944
                                     pulse_function=idle_function, digital_high=idle_digital,
945
                                     parameters=idle_params, use_as_tick=use_as_tick)
946
    return idle_element
947
948
949 View Code Duplication
def _get_trigger_element(self, length, increment, channel, use_as_tick=False, amp=None):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
950
    """
951
    Creates a trigger PulseBlockElement
952
953
    @param float length: trigger duration in seconds
954
    @param float increment: trigger duration increment in seconds
955
    @param string channel: The pulser channel to be triggered.
956
    @param bool use_as_tick: use as tick flag of the PulseBlockElement
957
    @param float amp: analog amplitude in case of analog channel in V
958
959
    @return: PulseBlockElement, the generated trigger element
960
    """
961
    # get channel lists
962
    digital_channels, analog_channels = self._get_channel_lists()
963
964
    # input params for trigger element generation
965
    trig_params = [{}] * self.analog_channels
966
    trig_digital = [False] * self.digital_channels
967
    trig_function = ['Idle'] * self.analog_channels
968
969
    # Determine analogue or digital trigger channel and set parameters accordingly.
970
    if 'd_ch' in channel:
971
        trig_index = digital_channels.index(channel)
972
        trig_digital[trig_index] = True
973
    elif 'a_ch' in channel:
974
        trig_index = analog_channels.index(channel)
975
        trig_function[trig_index] = 'DC'
976
        trig_params[trig_index] = {'amplitude1': amp}
977
978
    # Create trigger element
979
    trig_element = PulseBlockElement(init_length_s=length, increment_s=increment,
980
                                     pulse_function=trig_function, digital_high=trig_digital,
981
                                     parameters=trig_params, use_as_tick=use_as_tick)
982
    return trig_element
983
984
985
def _get_laser_element(self, length, increment, use_as_tick, delay_time=None, amp_V=None, gate_count_chnl=None):
986
    """
987
    Creates laser and gate trigger PulseBlockElements
988
989
    @param float length: laser pulse duration in seconds
990
    @param float increment: laser pulse duration increment in seconds
991
    @param bool use_as_tick: use as tick flag of the PulseBlockElement
992
    @param float delay_time: (aom-) delay after the laser trigger in seconds
993
                             (only for gated fast counter)
994
    @param float amp_V: Analog voltage for laser and gate trigger (if those channels are analog)
995
    @param string gate_count_chnl: the channel descriptor string for the gate trigger
996
997
    @return: PulseBlockElement, two elements for laser and gate trigger (delay element)
998
    """
999
    # get channel lists
1000
    digital_channels, analog_channels = self._get_channel_lists()
1001
1002
    # input params for laser element generation
1003
    laser_params = [{}] * self.analog_channels
1004
    laser_digital = [False] * self.digital_channels
1005
    laser_function = ['Idle'] * self.analog_channels
1006
    # input params for delay element generation (for gated fast counter)
1007
    delay_params = [{}] * self.analog_channels
1008
    delay_digital = [False] * self.digital_channels
1009
    delay_function = ['Idle'] * self.analog_channels
1010
1011
    # Determine analogue or digital laser channel and set parameters accordingly.
1012
    if 'd_ch' in self.laser_channel:
1013
        laser_index = digital_channels.index(self.laser_channel)
1014
        laser_digital[laser_index] = True
1015
    elif 'a_ch' in self.laser_channel:
1016
        laser_index = analog_channels.index(self.laser_channel)
1017
        laser_function[laser_index] = 'DC'
1018
        laser_params[laser_index] = {'amplitude1': amp_V}
1019
    # add gate trigger for gated fast counters
1020
    if gate_count_chnl is not None:
1021
        # Determine analogue or digital gate trigger and set parameters accordingly.
1022
        if 'd_ch' in gate_count_chnl:
1023
            gate_index = digital_channels.index(gate_count_chnl)
1024
            laser_digital[gate_index] = True
1025
            delay_digital[gate_index] = True
1026
        elif 'a_ch' in gate_count_chnl:
1027
            gate_index = analog_channels.index(gate_count_chnl)
1028
            laser_function[gate_index] = 'DC'
1029
            laser_params[gate_index] = {'amplitude1': amp_V}
1030
            delay_function[gate_index] = 'DC'
1031
            delay_params[gate_index] = {'amplitude1': amp_V}
1032
1033
    # Create laser element
1034
    laser_element = PulseBlockElement(init_length_s=length, increment_s=increment,
1035
                                      pulse_function=laser_function, digital_high=laser_digital,
1036
                                      parameters=laser_params, use_as_tick=use_as_tick)
1037
    # Create delay element
1038
    delay_element = PulseBlockElement(init_length_s=delay_time, increment_s=0.0,
1039
                                      pulse_function=delay_function, digital_high=delay_digital,
1040
                                      parameters=delay_params, use_as_tick=use_as_tick)
1041
    return laser_element, delay_element
1042
1043
1044 View Code Duplication
def _get_mw_element(self, length, increment, mw_channel, use_as_tick, amp=None, freq=None,
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1045
                    phase=None):
1046
    """
1047
    Creates a MW pulse PulseBlockElement
1048
1049
    @param float length: MW pulse duration in seconds
1050
    @param float increment: MW pulse duration increment in seconds
1051
    @param string mw_channel: The pulser channel controlling the MW. If set to 'd_chX' this will be
1052
                              interpreted as trigger for an external microwave source. If set to
1053
                              'a_chX' the pulser (AWG) will act as microwave source.
1054
    @param bool use_as_tick: use as tick flag of the PulseBlockElement
1055
    @param float freq: MW frequency in case of analogue MW channel in Hz
1056
    @param float amp: MW amplitude in case of analogue MW channel in V
1057
    @param float phase: MW phase in case of analogue MW channel in deg
1058
1059
    @return: PulseBlockElement, the generated MW element
1060
    """
1061
    # get channel lists
1062
    digital_channels, analog_channels = self._get_channel_lists()
1063
1064
    # input params for MW element generation
1065
    mw_params = [{}] * self.analog_channels
1066
    mw_digital = [False] * self.digital_channels
1067
    mw_function = ['Idle'] * self.analog_channels
1068
1069
    # Determine analogue or digital MW channel and set parameters accordingly.
1070
    if 'd_ch' in mw_channel:
1071
        mw_index = digital_channels.index(mw_channel)
1072
        mw_digital[mw_index] = True
1073
    elif 'a_ch' in mw_channel:
1074
        mw_index = analog_channels.index(mw_channel)
1075
        mw_function[mw_index] = 'Sin'
1076
        mw_params[mw_index] = {'amplitude1': amp, 'frequency1': freq, 'phase1': phase}
1077
1078
    # Create MW element
1079
    mw_element = PulseBlockElement(init_length_s=length, increment_s=increment,
1080
                                   pulse_function=mw_function, digital_high=mw_digital,
1081
                                   parameters=mw_params, use_as_tick=use_as_tick)
1082
    return mw_element
1083
1084
1085
def _get_mw_laser_element(self, length, increment, mw_channel, use_as_tick, delay_time=None,
1086
                          laser_amp=None, mw_amp=None, mw_freq=None, mw_phase=None,
1087
                          gate_count_chnl=None):
1088
    """
1089
1090
    @param length:
1091
    @param increment:
1092
    @param mw_channel:
1093
    @param use_as_tick:
1094
    @param delay_time:
1095
    @param laser_amp:
1096
    @param mw_amp:
1097
    @param mw_freq:
1098
    @param mw_phase:
1099
    @param gate_count_chnl:
1100
    @return:
1101
    """
1102
    # get channel lists
1103
    digital_channels, analog_channels = self._get_channel_lists()
1104
1105
    # input params for laser/mw element generation
1106
    laser_mw_params = [{}] * self.analog_channels
1107
    laser_mw_digital = [False] * self.digital_channels
1108
    laser_mw_function = ['Idle'] * self.analog_channels
1109
    # input params for delay element generation (for gated fast counter)
1110
    delay_params = [{}] * self.analog_channels
1111
    delay_digital = [False] * self.digital_channels
1112
    delay_function = ['Idle'] * self.analog_channels
1113
1114
    # Determine analogue or digital laser channel and set parameters accordingly.
1115
    if 'd_ch' in self.laser_channel:
1116
        laser_index = digital_channels.index(self.laser_channel)
1117
        laser_mw_digital[laser_index] = True
1118
    elif 'a_ch' in self.laser_channel:
1119
        laser_index = analog_channels.index(self.laser_channel)
1120
        laser_mw_function[laser_index] = 'DC'
1121
        laser_mw_params[laser_index] = {'amplitude1': laser_amp}
1122
    # add gate trigger for gated fast counters
1123
    if gate_count_chnl is not None:
1124
        # Determine analogue or digital gate trigger and set parameters accordingly.
1125
        if 'd_ch' in gate_count_chnl:
1126
            gate_index = digital_channels.index(gate_count_chnl)
1127
            laser_mw_digital[gate_index] = True
1128
            delay_digital[gate_index] = True
1129
        elif 'a_ch' in gate_count_chnl:
1130
            gate_index = analog_channels.index(gate_count_chnl)
1131
            laser_mw_function[gate_index] = 'DC'
1132
            laser_mw_params[gate_index] = {'amplitude1': laser_amp}
1133
            delay_function[gate_index] = 'DC'
1134
            delay_params[gate_index] = {'amplitude1': laser_amp}
1135
    # Determine analogue or digital MW channel and set parameters accordingly.
1136
    if 'd_ch' in mw_channel:
1137
        mw_index = digital_channels.index(mw_channel)
1138
        laser_mw_digital[mw_index] = True
1139
    elif 'a_ch' in mw_channel:
1140
        mw_index = analog_channels.index(mw_channel)
1141
        laser_mw_function[mw_index] = 'Sin'
1142
        laser_mw_params[mw_index] = {'amplitude1': mw_amp, 'frequency1': mw_freq,
1143
                                     'phase1': mw_phase}
1144
1145
    # Create laser/mw element
1146
    laser_mw_element = PulseBlockElement(init_length_s=length, increment_s=increment,
1147
                                         pulse_function=laser_mw_function,
1148
                                         digital_high=laser_mw_digital, parameters=laser_mw_params,
1149
                                         use_as_tick=use_as_tick)
1150
    if gate_count_chnl is not None:
1151
        # Create delay element
1152
        delay_element = PulseBlockElement(init_length_s=delay_time, increment_s=0.0,
1153
                                          pulse_function=delay_function, digital_high=delay_digital,
1154
                                          parameters=delay_params, use_as_tick=False)
1155
        return laser_mw_element, delay_element
1156
    else:
1157
        return laser_mw_element
1158
1159
1160
def _do_channel_sanity_checks(self, **kwargs):
1161
    """
1162
    Does sanity checks of specified channels
1163
1164
    @param string kwargs: all channel descriptors to be checked (except laser channel)
1165
1166
    @return: error code (0: specified channels OK, -1: specified channels not OK)
1167
    """
1168
    # sanity checks
1169
    error_code = 0
1170
    for channel in kwargs:
1171
        if kwargs[channel] is not None and kwargs[channel] != '':
1172
            if kwargs[channel] not in self.activation_config:
1173
                self.log.error('{0} "{1}" is not part of current activation_config!'
1174
                               ''.format(channel, kwargs[channel]))
1175
                error_code = -1
1176
    return error_code
1177