def apply_mixer_predistortion_corrections(self, wave_dict): M_G = wf.mixer_predistortion_matrix(self.G_mixer_alpha(), self.G_mixer_phi()) M_D = wf.mixer_predistortion_matrix(self.D_mixer_alpha(), self.D_mixer_phi()) for key, val in wave_dict.items(): GI, GQ = np.dot(M_G, val[0:2]) # Mixer correction Gaussian comp. DI, DQ = np.dot(M_D, val[2:4]) # Mixer correction Derivative comp. wave_dict[key] = GI, GQ, DI, DQ return wave_dict
def apply_mixer_predistortion_corrections(self, wave_dict): M = wf.mixer_predistortion_matrix(self.mixer_alpha(), self.mixer_phi()) self.AWG.get_instr().set( 'ch_pair{}_transform_matrix'.format(self.channel_I()), M) # in the QWG the predistortion matrix is implemented in hardware # and does not modify the actual wave dict. # the wave dict is still returned unmodified to preserve the # call signature as required for HDAWG compatibility. return wave_dict
def generate_standard_waveforms(self): """ Generates waveforms for reading out from each individual resonator. """ # Only generate the combinations required/specified in the LutMap # RO pulses sampling_rate = self.get('sampling_rate') # Prepare gauss pulse for convolution (if desired) if self.gaussian_convolution(): if self.pulse_primitive_shape() != 'square': print("Warning: recommend to set pulse_primitive_shape to " + "'square' when using gaussian_convolution.") sigma = self.gaussian_convolution_sigma() def norm_gauss(x, mu, sigma): n = 1 / (sigma * np.sqrt(2 * np.pi)) return n * np.exp((-((x - mu) / sigma)**2) / 2) gauss_length = 6 * sigma # in units of time hgsl = int(gauss_length * sampling_rate / 2) # half no. of samples gauss_sample_length = hgsl * 2 # no. of samples gauss_samples = np.arange(0, gauss_sample_length, 1) / sampling_rate norm_gauss_p = norm_gauss(x=gauss_samples, mu=gauss_length / 2, sigma=sigma) else: gauss_length = 0 # Prepare pulses for all resonators self._wave_dict = {} for res in self._resonator_codeword_bit_mapping: res_wave_dict = {} # 1. Generate Pulse envelopes # Simple pulse up_len = self.get('M_length_R{}'.format(res)) - gauss_length M = create_pulse(shape=self.pulse_primitive_shape(), amplitude=self.get('M_amp_R{}'.format(res)), length=up_len, delay=0, phase=self.get('M_phi_R{}'.format(res)), sampling_rate=sampling_rate) res_wave_dict['M_simple_R{}'.format(res)] = M # 3-step RO pulse with ramp-up and double depletion up_len = self.get('M_length_R{}'.format(res)) - gauss_length / 2 M_up = create_pulse(shape=self.pulse_primitive_shape(), amplitude=self.get('M_amp_R{}'.format(res)), length=up_len, delay=0, phase=self.get('M_phi_R{}'.format(res)), sampling_rate=sampling_rate) M_down0 = create_pulse( shape=self.pulse_primitive_shape(), amplitude=self.get('M_down_amp0_R{}'.format(res)), length=self.get('M_down_length0_R{}'.format(res)), # ns delay=0, phase=self.get('M_down_phi0_R{}'.format(res)), sampling_rate=sampling_rate) down1_len = self.get( 'M_down_length1_R{}'.format(res)) - gauss_length / 2 M_down1 = create_pulse( shape=self.pulse_primitive_shape(), amplitude=self.get('M_down_amp1_R{}'.format(res)), length=down1_len, delay=0, phase=self.get('M_down_phi1_R{}'.format(res)), sampling_rate=sampling_rate) M_up_down_down = (np.concatenate( (M_up[0], M_down0[0], M_down1[0])), np.concatenate( (M_up[1], M_down0[1], M_down1[1]))) res_wave_dict['M_up_down_down_R{}'.format(res)] = M_up_down_down # pulse with up, down, down depletion with an additional final # strong measurement at some delay M_final = create_pulse( shape=self.pulse_primitive_shape(), amplitude=self.get('M_final_amp_R{}'.format(res)), length=self.get('M_final_length_R{}'.format(res)), # ns delay=self.get('M_final_delay_R{}'.format(res)), phase=self.get('M_phi_R{}'.format(res)), sampling_rate=sampling_rate) M_up_down_down_final = (np.concatenate( (M_up_down_down[0], M_final[0])), np.concatenate( (M_up_down_down[1], M_final[1]))) res_wave_dict['M_up_down_down_final_R{}'.format( res)] = M_up_down_down_final # 2. convolve with gaussian (if desired) if self.gaussian_convolution(): for key, val in res_wave_dict.items(): M_conv0 = np.convolve(val[0], norm_gauss_p) M_conv1 = np.convolve(val[1], norm_gauss_p) #M_conv0 = M_conv0[hgsl: -hgsl+1] #M_conv1 = M_conv1[hgsl: -hgsl+1] res_wave_dict[key] = (M_conv0 / sampling_rate, M_conv1 / sampling_rate) # 3. modulation with base frequency for key, val in res_wave_dict.items(): res_wave_dict[key] = wf.mod_pulse( pulse_I=val[0], pulse_Q=val[1], f_modulation=self.get('M_modulation_R{}'.format(res)), sampling_rate=self.get('sampling_rate')) # 4. apply mixer predistortion if self.mixer_apply_predistortion_matrix(): Mat = wf.mixer_predistortion_matrix(self.mixer_alpha(), self.mixer_phi()) for key, val in res_wave_dict.items(): res_wave_dict[key] = np.dot(Mat, val) # 5. Add to global dict self._wave_dict.update(**res_wave_dict) return self._wave_dict
def apply_mixer_predistortion_corrections(self, wave_dict): M = wf.mixer_predistortion_matrix(self.mixer_alpha(), self.mixer_phi()) for key, val in wave_dict.items(): wave_dict[key] = np.dot(M, val) return wave_dict