def generate_xy8_qdyne(self, name='XY8_Qdyne', rabi_period=1.0e-8, mw_freq=2870.0e6, mw_amp=0.5, tau=0.5e-6, xy8_order=4, frequency=1.0e6, mw_channel='a_ch1', laser_length=3.0e-7, channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6, seq_trig_channel='d_ch1', gate_count_channel=''): """ """ # pre-computations period = 1 / frequency rabi_period = self._adjust_to_samplingrate(rabi_period, 4) tau = self._adjust_to_samplingrate(tau, 2) laser_length = self._adjust_to_samplingrate(laser_length, 1) delay_length = self._adjust_to_samplingrate(delay_length, 1) #trigger + 8*N tau + 2*pi/2 pulse + 2*tauhalf_excess + laser_length + aom_delay + wait_time sequence_length = 20.0e-9 + 8 * xy8_order * tau + rabi_period / 2 + laser_length + delay_length + wait_time if (sequence_length % period) == 0: extra_time = 0 else: extra_time = period - (sequence_length % period) extra_time = self._adjust_to_samplingrate(extra_time, 1) # Sanity checks if gate_count_channel == '': gate_count_channel = None if seq_trig_channel == '': seq_trig_channel = None err_code = self._do_channel_sanity_checks( mw_channel=mw_channel, gate_count_channel=gate_count_channel, seq_trig_channel=seq_trig_channel) if err_code != 0: return # calculate "real" start length of the waiting times (tau and tauhalf) real_start_tau = tau - rabi_period / 2 real_start_tauhalf = tau / 2 - rabi_period / 4 if real_start_tau < 0.0 or real_start_tauhalf < 0.0: self.log.error( 'XY8_Qdyne generation failed! Rabi period of {0:.3e} s is too long for start tau ' 'of {1:.3e} s.'.format(rabi_period, tau)) return # get waiting element waiting_element = self._get_idle_element(wait_time + extra_time, 0.0, False) # get laser and delay element laser_element, delay_element = self._get_laser_element( laser_length, 0.0, False, delay_length, channel_amp, gate_count_channel) # get pihalf element pihalf_element = self._get_mw_element(rabi_period / 4.0, 0.0, mw_channel, False, mw_amp, mw_freq, 0.0) # get -x pihalf (3pihalf) element pi3half_element = self._get_mw_element(rabi_period / 4.0, 0.0, mw_channel, False, mw_amp, mw_freq, 180.) # get pi elements pix_element = self._get_mw_element(rabi_period / 2.0, 0.0, mw_channel, False, mw_amp, mw_freq, 0.0) piy_element = self._get_mw_element(rabi_period / 2.0, 0.0, mw_channel, False, mw_amp, mw_freq, 90.0) # get tauhalf element tauhalf_element = self._get_idle_element(real_start_tauhalf, 0, False) # get tau element tau_element = self._get_idle_element(real_start_tau, 0, False) if seq_trig_channel is not None: # get sequence trigger element seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp) # Create its own block out of the element seq_block = PulseBlock('seq_trigger', [seqtrig_element]) # save block self.save_block('seq_trigger', seq_block) # create XY8-N_qdyne block element list elem_list = [] elem_list.append(laser_element) elem_list.append(delay_element) elem_list.append(waiting_element) # actual Qdyne XY8 sequence elem_list.append(pihalf_element) elem_list.append(tauhalf_element) for n in range(xy8_order): elem_list.append(pix_element) elem_list.append(tau_element) elem_list.append(piy_element) elem_list.append(tau_element) elem_list.append(pix_element) elem_list.append(tau_element) elem_list.append(piy_element) elem_list.append(tau_element) elem_list.append(piy_element) elem_list.append(tau_element) elem_list.append(pix_element) elem_list.append(tau_element) elem_list.append(piy_element) elem_list.append(tau_element) elem_list.append(pix_element) if n != xy8_order - 1: elem_list.append(tau_element) elem_list.append(tauhalf_element) elem_list.append(pi3half_element) # create XY8-N block object block = PulseBlock(name, elem_list) self.save_block(name, block) # create block list and ensemble object block_list = [(block, 0)] if seq_trig_channel is not None: block_list.append((seq_block, 0)) # create ensemble out of the block(s) block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True) # add metadata to invoke settings later on block_ensemble.sample_rate = self.sample_rate block_ensemble.activation_config = self.activation_config block_ensemble.amplitude_dict = self.amplitude_dict block_ensemble.laser_channel = self.laser_channel block_ensemble.alternating = False block_ensemble.laser_ignore_list = [] # save ensemble self.save_ensemble(name, block_ensemble) return block_ensemble
def generate_cpmg_nsweep(self, name='CPMG_Nsweep', rabi_period=1.0e-8, mw_freq=2870.0e6, mw_amp=0.1, tau=0.5e-6, start_n=1, incr_n=1, num_of_points=50, mw_channel='a_ch1', laser_length=3.0e-6, channel_amp=1.0, delay_length=0.7e-6, wait_time=1.0e-6, seq_trig_channel='', gate_count_channel='', alternating=True): """ """ # Sanity checks if gate_count_channel == '': gate_count_channel = None if seq_trig_channel == '': seq_trig_channel = None err_code = self._do_channel_sanity_checks( mw_channel=mw_channel, gate_count_channel=gate_count_channel, seq_trig_channel=seq_trig_channel) if err_code != 0: return # get pulse number array for measurement ticks n_array = start_n + np.arange(num_of_points) * incr_n n_array.astype(int) # calculate "real" start length of the waiting times (tau and tauhalf) real_tau = tau - rabi_period / 2 real_tauhalf = tau / 2 - 3 * rabi_period / 8 if real_tau < 0.0 or real_tauhalf < 0.0: self.log.error( 'CPMG-N-sweep generation failed! Rabi period of {0:.3e} s is too long for start tau ' 'of {1:.3e} s.'.format(rabi_period, tau)) return # get waiting element waiting_element = self._get_idle_element(wait_time, 0.0, False) # get laser and delay element laser_element, delay_element = self._get_laser_element( laser_length, 0.0, False, delay_length, channel_amp, gate_count_channel) # get pihalf element pihalf_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq, 0.0) # get -x pihalf (3pihalf) element pi3half_element = self._get_mw_element(rabi_period / 4, 0.0, mw_channel, False, mw_amp, mw_freq, 180.) # get pi elements piy_element = self._get_mw_element(rabi_period / 2, 0.0, mw_channel, False, mw_amp, mw_freq, 90.0) # get tauhalf element tauhalf_element = self._get_idle_element(real_tauhalf, 0, False) # get tau element tau_element = self._get_idle_element(real_tau, 0, False) if seq_trig_channel is not None: # get sequence trigger element seqtrig_element = self._get_trigger_element(20.0e-9, 0.0, seq_trig_channel, amp=channel_amp) # Create its own block out of the element seq_block = PulseBlock('seq_trigger', [seqtrig_element]) # save block self.save_block('seq_trigger', seq_block) # create CPMG-N block element list elem_list = [] # actual CPMG-N-sweep sequence for outer_counter, outer_element in enumerate(n_array): elem_list.append(pihalf_element) elem_list.append(tauhalf_element) for n in range(outer_element): elem_list.append(piy_element) if n != outer_element - 1: elem_list.append(tau_element) elem_list.append(tauhalf_element) elem_list.append(pihalf_element) elem_list.append(laser_element) elem_list.append(delay_element) elem_list.append(waiting_element) if alternating: elem_list.append(pihalf_element) elem_list.append(tauhalf_element) for n in range(outer_element): elem_list.append(piy_element) if n != outer_element - 1: elem_list.append(tau_element) elem_list.append(tauhalf_element) elem_list.append(pi3half_element) elem_list.append(laser_element) elem_list.append(delay_element) elem_list.append(waiting_element) # create CPMG-N block object block = PulseBlock(name, elem_list) self.save_block(name, block) # create block list and ensemble object block_list = [(block, 0)] if seq_trig_channel is not None: block_list.append((seq_block, 0)) # create ensemble out of the block(s) block_ensemble = PulseBlockEnsemble(name=name, block_list=block_list, rotating_frame=True) # add metadata to invoke settings later on block_ensemble.sample_rate = self.sample_rate block_ensemble.activation_config = self.activation_config block_ensemble.amplitude_dict = self.amplitude_dict block_ensemble.laser_channel = self.laser_channel block_ensemble.alternating = True block_ensemble.laser_ignore_list = [] block_ensemble.controlled_vals_array = n_array # save ensemble self.save_ensemble(name, block_ensemble) return block_ensemble