diff --git a/CHANGELOG.md b/CHANGELOG.md index f56a6c8b63ed3a9465d8ae85b797a37c82e83c6e..b00f69fe66d1a2987c8869fa3522a8de13a3530c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to Pulselib will be documented in this file. +## \[1.7.13] - 2024-03-08 + +- Performance improvement in MW pulse processing. (30% gain in precompile of randomized benchmarking.) + ## \[1.7.12] - 2024-03-07 - Modified Keysight_QS backend to drive qubits without MW source using plunger and barrier gates. diff --git a/pulse_lib/segments/data_classes/data_pulse.py b/pulse_lib/segments/data_classes/data_pulse.py index 8e1f2b44d81fa28d268e6a148a05dd8b403fb454..46640816aa385c03f69d9c5272cf0bdc279e8b72 100644 --- a/pulse_lib/segments/data_classes/data_pulse.py +++ b/pulse_lib/segments/data_classes/data_pulse.py @@ -292,36 +292,6 @@ class pulse_data(parent_data): self._phase_shifts_consolidated = False self.update_end_time(time + other.total_time) - def shift_MW_frequency(self, frequency): - ''' - shift the frequency of a MW signal. This is needed for dealing with the upconverion of a IQ signal. - - Args: - frequency (float) : frequency you want to shift - ''' - for mw_pulse in self.MW_pulse_data: - mw_pulse.frequency -= frequency - - for chirp in self.chirp_data: - chirp.start_frequency -= frequency - chirp.stop_frequency -= frequency - - def shift_MW_phases(self, phase_shift): - ''' - Shift the phases of all the microwaves present in the MW data object - - Args: - phase_shift (float) : amount of phase to shift in rad. - ''' - if phase_shift == 0: - return - - for mw_pulse in self.MW_pulse_data: - mw_pulse.phase_offset += phase_shift - - for chirp in self.chirp_data: - chirp.phase += phase_shift - def __copy__(self): # NOTE: Copy is called in pulse_data_all, before adding virtual channels. # It is also called when a dimension is added in looping. @@ -627,6 +597,40 @@ class pulse_data(parent_data): elements.sort(key=lambda p: (p.start, p.stop)) return elements + def get_IQ_data(self, gain, frequency_shift, phase_shift): + ''' + Returns MW data with modified amplitude, frequency and phase. + + Args: + gain (float): amplitude gain + frequency_shift (float): frequency shift + phase_shift (float): phase shift + ''' + self._consolidate_phase_shifts() + new_data = pulse_data() + + new_data.MW_pulse_data = copy.deepcopy(self.MW_pulse_data) + for mw_pulse in new_data.MW_pulse_data: + mw_pulse.amplitude *= gain + mw_pulse.frequency -= frequency_shift + mw_pulse.phase_offset += phase_shift + + new_data.chirp_data = copy.deepcopy(self.chirp_data) + for chirp in new_data.chirp_data: + chirp.amplitude *= gain + chirp.start_frequency -= frequency_shift + chirp.stop_frequency -= frequency_shift + chirp.phase += phase_shift + + new_data.phase_shifts = copy.copy(self.phase_shifts) + new_data.end_time = self.end_time + new_data.start_time = self.start_time + new_data._hres = self._hres + new_data._consolidated = self._consolidated + new_data._phase_shifts_consolidated = self._phase_shifts_consolidated + + return new_data + def _render(self, sample_rate, ref_channel_states, LO): ''' make a full rendering of the waveform at a predetermined sample rate. diff --git a/pulse_lib/segments/segment_IQ.py b/pulse_lib/segments/segment_IQ.py index d6070fd4629c725a44ea16f8a3f4698cb985f5d8..89981047d532ad2ce6c0997db6fb12aef9a796f9 100644 --- a/pulse_lib/segments/segment_IQ.py +++ b/pulse_lib/segments/segment_IQ.py @@ -82,7 +82,7 @@ class segment_IQ(segment_base): Add chirp to the segment. Args: t0(float) : start time in ns - t1(float) : stop tiume in ns + t1(float) : stop time in ns f0(float) : start frequency f1 (float) : stop frequency amp (float) : amplitude of the pulse. @@ -115,12 +115,11 @@ class segment_IQ(segment_base): if out_channel_info.image == '-': phase_shift += np.pi - local_data = copy.copy(self.data).flatten() + data = self.data + local_data = data_container(shape=data.shape).flatten() # downconvert the sigal saved in the data object, so later on, in the real MW source, it can be upconverted again. - for i in range(len(local_data)): - local_data[i] = self.data.flat[i] * correction_gain - local_data[i].shift_MW_phases(phase_shift) - local_data[i].shift_MW_frequency(LO) + for i in range(data.size): + local_data[i] = data.flat[i].get_IQ_data(correction_gain, LO, phase_shift) local_data = local_data.reshape(self.data.shape)