Skip to content
Snippets Groups Projects
Commit 63d49aac authored by Sander Snoo's avatar Sander Snoo
Browse files

OffsetRamp time,duration -> start,stop

Faster sorting of elements
parent dbdb654a
No related branches found
No related tags found
No related merge requests found
...@@ -459,7 +459,7 @@ class SegmentRenderInfo: ...@@ -459,7 +459,7 @@ class SegmentRenderInfo:
class UploadAggregator: class UploadAggregator:
verbose = True verbose = False
def __init__(self, q1instrument, awg_channels, marker_channels, digitizer_channels, def __init__(self, q1instrument, awg_channels, marker_channels, digitizer_channels,
qubit_channels, awg_voltage_channels, marker_sequencers, seq_markers): qubit_channels, awg_voltage_channels, marker_sequencers, seq_markers):
...@@ -630,8 +630,8 @@ class UploadAggregator: ...@@ -630,8 +630,8 @@ class UploadAggregator:
entries = data.get_data_elements() entries = data.get_data_elements()
for e in entries: for e in entries:
if isinstance(e, OffsetRamp): if isinstance(e, OffsetRamp):
t = PulsarConfig.align(e.time + seg_start) t = PulsarConfig.align(e.start + seg_start)
t_end = PulsarConfig.align(e.time + seg_start + e.duration) t_end = PulsarConfig.align(e.stop + seg_start)
v_start = scaling * e.v_start v_start = scaling * e.v_start
v_stop = scaling * e.v_stop v_stop = scaling * e.v_stop
duration = t_end - t duration = t_end - t
......
...@@ -67,10 +67,10 @@ class pulse_delta: ...@@ -67,10 +67,10 @@ class pulse_delta:
@property @property
def is_near_zero(self): def is_near_zero(self):
# near zero if |step| < 1 uV and |ramp| < 1e-9 mV/ns (= 1 mV/s) # near zero if |step| < 0.001 uV and |ramp| < 1e-9 mV/ns (= 1 mV/s)
# note: max ramp: 2V/ns = 2000 mV/ns, min ramp: 1 mV/s = 1e-9 mV/ns. ~ 12 orders of magnitude. # note: max ramp: 2V/ns = 2000 mV/ns, min ramp: 1 mV/s = 1e-9 mV/ns. ~ 12 orders of magnitude.
# Regular floats have 16 digits precision. # Regular floats have 16 digits precision.
return -1e-3 < self.step < 1e-3 and -1e-9 < self.ramp < 1e-9 return -1e-6 < self.step < 1e-6 and -1e-9 < self.ramp < 1e-9
@dataclass @dataclass
class custom_pulse_element: class custom_pulse_element:
...@@ -119,17 +119,18 @@ class PhaseShift: ...@@ -119,17 +119,18 @@ class PhaseShift:
def start(self): def start(self):
return self.time return self.time
@property
def stop(self):
return self.time
# Changed [v1.6.0]
@dataclass @dataclass
class OffsetRamp: class OffsetRamp:
time: float start: float
duration: float # time till next OffsetRamp stop: float # time of next OffsetRamp
v_start: float v_start: float
v_stop: float v_stop: float
@property
def start(self):
return self.time
# keep till end: start = np.inf # keep till end: start = np.inf
# slicing: # slicing:
# consolidate all in slice on `end`, keep `inf`. delta_new = sum(p.delta for p in slice), ... # consolidate all in slice on `end`, keep `inf`. delta_new = sum(p.delta for p in slice), ...
...@@ -152,7 +153,6 @@ class pulse_data(parent_data): ...@@ -152,7 +153,6 @@ class pulse_data(parent_data):
self.start_time = 0 self.start_time = 0
self._end_time = 0 self._end_time = 0
self.global_phase = 0
self._consolidated = False self._consolidated = False
self._preprocessed = False self._preprocessed = False
...@@ -290,8 +290,8 @@ class pulse_data(parent_data): ...@@ -290,8 +290,8 @@ class pulse_data(parent_data):
Args: Args:
frequency (float) : frequency you want to shift frequency (float) : frequency you want to shift
''' '''
for IQ_data_single_object in self.MW_pulse_data: for mw_pulse in self.MW_pulse_data:
IQ_data_single_object.frequency -= frequency mw_pulse.frequency -= frequency
def shift_MW_phases(self, phase_shift): def shift_MW_phases(self, phase_shift):
''' '''
...@@ -303,8 +303,8 @@ class pulse_data(parent_data): ...@@ -303,8 +303,8 @@ class pulse_data(parent_data):
if phase_shift == 0: if phase_shift == 0:
return return
for IQ_data_single_object in self.MW_pulse_data: for mw_pulse in self.MW_pulse_data:
IQ_data_single_object.start_phase += phase_shift mw_pulse.start_phase += phase_shift
''' '''
...@@ -319,8 +319,6 @@ class pulse_data(parent_data): ...@@ -319,8 +319,6 @@ class pulse_data(parent_data):
my_copy.phase_shifts = copy.copy(self.phase_shifts) my_copy.phase_shifts = copy.copy(self.phase_shifts)
my_copy.custom_pulse_data = copy.deepcopy(self.custom_pulse_data) my_copy.custom_pulse_data = copy.deepcopy(self.custom_pulse_data)
my_copy.start_time = copy.copy(self.start_time) my_copy.start_time = copy.copy(self.start_time)
my_copy.software_marker_data = copy.copy(self.software_marker_data)
my_copy.global_phase = copy.copy(self.global_phase)
my_copy._end_time = self._end_time my_copy._end_time = self._end_time
my_copy._consolidated = self._consolidated my_copy._consolidated = self._consolidated
...@@ -332,7 +330,6 @@ class pulse_data(parent_data): ...@@ -332,7 +330,6 @@ class pulse_data(parent_data):
''' '''
new_data = pulse_data() new_data = pulse_data()
new_data.start_time = copy.copy(self.start_time) new_data.start_time = copy.copy(self.start_time)
new_data.global_phase = copy.copy(self.global_phase)
if isinstance(other, pulse_data): if isinstance(other, pulse_data):
new_data.pulse_deltas = self.pulse_deltas + other.pulse_deltas new_data.pulse_deltas = self.pulse_deltas + other.pulse_deltas
...@@ -383,6 +380,8 @@ class pulse_data(parent_data): ...@@ -383,6 +380,8 @@ class pulse_data(parent_data):
''' '''
multiplication operator for segment_single multiplication operator for segment_single
''' '''
# consolidate to reduce number of elements.
# multiplication is applied during rendering a good moment to reduce number of elements.
self._consolidate() self._consolidate()
new_data = pulse_data() new_data = pulse_data()
...@@ -393,8 +392,8 @@ class pulse_data(parent_data): ...@@ -393,8 +392,8 @@ class pulse_data(parent_data):
delta *= other delta *= other
new_data.MW_pulse_data = copy.deepcopy(self.MW_pulse_data) new_data.MW_pulse_data = copy.deepcopy(self.MW_pulse_data)
for IQ_data_single_object in new_data.MW_pulse_data: for mw_pulse in new_data.MW_pulse_data:
IQ_data_single_object.amplitude *=other mw_pulse.amplitude *=other
new_data.custom_pulse_data = copy.deepcopy(self.custom_pulse_data) new_data.custom_pulse_data = copy.deepcopy(self.custom_pulse_data)
for custom_pulse in new_data.custom_pulse_data: for custom_pulse in new_data.custom_pulse_data:
...@@ -403,8 +402,6 @@ class pulse_data(parent_data): ...@@ -403,8 +402,6 @@ class pulse_data(parent_data):
new_data.phase_shifts = copy.copy(self.phase_shifts) new_data.phase_shifts = copy.copy(self.phase_shifts)
new_data._end_time = self._end_time new_data._end_time = self._end_time
new_data.start_time = self.start_time new_data.start_time = self.start_time
new_data.software_marker_data = copy.copy(self.software_marker_data)
new_data.global_phase = self.global_phase
new_data._consolidated = True new_data._consolidated = True
else: else:
raise TypeError(f'Cannot multiply pulse_data with {type(other)}') raise TypeError(f'Cannot multiply pulse_data with {type(other)}')
...@@ -498,29 +495,17 @@ class pulse_data(parent_data): ...@@ -498,29 +495,17 @@ class pulse_data(parent_data):
return integrated_value return integrated_value
def get_data_elements(self): def get_data_elements(self):
def typeorder(obj):
if isinstance(obj, PhaseShift):
return 0.1
if isinstance(obj, OffsetRamp):
return 0.2
if isinstance(obj, IQ_data_single):
return 0.3
if isinstance(obj, custom_pulse_element):
return 0.4
elements = [] elements = []
self._pre_process() self._pre_process()
for time, duration, v_start, v_stop in zip(self._times, self._intervals, for time, duration, v_start, v_stop in zip(self._times, self._intervals,
self._amplitudes, self._amplitudes_end): self._amplitudes, self._amplitudes_end):
elements.append(OffsetRamp(time, duration, v_start, v_stop)) elements.append(OffsetRamp(time, time+duration, v_start, v_stop))
elements += self.custom_pulse_data elements += self.custom_pulse_data
elements += self.MW_pulse_data elements += self.MW_pulse_data
elements += self.phase_shifts elements += self.phase_shifts
# Sort on rounded time, next: PhaseShift,Offset,MW_pulse,custom elements.sort(key=lambda p:(p.start,p.stop))
elements.sort(key=lambda p:(int(p.start+0.5)+typeorder(p)))
return elements return elements
def _render(self, sample_rate, ref_channel_states, LO): def _render(self, sample_rate, ref_channel_states, LO):
''' '''
make a full rendering of the waveform at a predetermined sample rate. make a full rendering of the waveform at a predetermined sample rate.
...@@ -555,28 +540,28 @@ class pulse_data(parent_data): ...@@ -555,28 +540,28 @@ class pulse_data(parent_data):
ps_ch = phase_shifts_channels.setdefault(ps.channel_name, []) ps_ch = phase_shifts_channels.setdefault(ps.channel_name, [])
ps_ch.append(ps) ps_ch.append(ps)
for IQ_data_single_object in self.MW_pulse_data: for mw_pulse in self.MW_pulse_data:
# start stop time of MW pulse # start stop time of MW pulse
start_pulse = IQ_data_single_object.start start_pulse = mw_pulse.start
stop_pulse = IQ_data_single_object.stop stop_pulse = mw_pulse.stop
# max amp, freq and phase. # max amp, freq and phase.
amp = IQ_data_single_object.amplitude amp = mw_pulse.amplitude
freq = IQ_data_single_object.frequency freq = mw_pulse.frequency
if LO: if LO:
freq -= LO freq -= LO
if abs(freq) > sample_rate*1e9/2: if abs(freq) > sample_rate*1e9/2:
raise Exception(f'Frequency {freq*1e-6:5.1f} MHz is above Nyquist frequency ({sample_rate*1e3/2} MHz)') raise Exception(f'Frequency {freq*1e-6:5.1f} MHz is above Nyquist frequency ({sample_rate*1e3/2} MHz)')
# TODO add check on configurable bandwidth. # TODO add check on configurable bandwidth.
phase = IQ_data_single_object.start_phase phase = mw_pulse.start_phase
if ref_channel_states and IQ_data_single_object.ref_channel in ref_channel_states.start_phase: if ref_channel_states and mw_pulse.ref_channel in ref_channel_states.start_phase:
ref_start_time = ref_channel_states.start_time ref_start_time = ref_channel_states.start_time
ref_start_phase = ref_channel_states.start_phase[IQ_data_single_object.ref_channel] ref_start_phase = ref_channel_states.start_phase[mw_pulse.ref_channel]
if IQ_data_single_object.ref_channel in phase_shifts_channels: if mw_pulse.ref_channel in phase_shifts_channels:
phase_shifts = [ phase_shifts = [
ps.phase_shift ps.phase_shift
for ps in phase_shifts_channels[IQ_data_single_object.ref_channel] for ps in phase_shifts_channels[mw_pulse.ref_channel]
if ps.time <= start_pulse if ps.time <= start_pulse
] ]
phase_shift = sum(phase_shifts) phase_shift = sum(phase_shifts)
...@@ -588,11 +573,11 @@ class pulse_data(parent_data): ...@@ -588,11 +573,11 @@ class pulse_data(parent_data):
phase_shift = 0 phase_shift = 0
# envelope data of the pulse # envelope data of the pulse
if IQ_data_single_object.envelope is None: if mw_pulse.envelope is None:
IQ_data_single_object.envelope = envelope_generator() mw_pulse.envelope = envelope_generator()
amp_envelope = IQ_data_single_object.envelope.get_AM_envelope((stop_pulse - start_pulse), sample_rate) amp_envelope = mw_pulse.envelope.get_AM_envelope((stop_pulse - start_pulse), sample_rate)
phase_envelope = np.asarray(IQ_data_single_object.envelope.get_PM_envelope((stop_pulse - start_pulse), sample_rate)) phase_envelope = np.asarray(mw_pulse.envelope.get_PM_envelope((stop_pulse - start_pulse), sample_rate))
#self.baseband_pulse_data[-1,0] convert to point numbers #self.baseband_pulse_data[-1,0] convert to point numbers
n_pt = int((stop_pulse - start_pulse) * sample_rate) if isinstance(amp_envelope, float) else len(amp_envelope) n_pt = int((stop_pulse - start_pulse) * sample_rate) if isinstance(amp_envelope, float) else len(amp_envelope)
...@@ -638,7 +623,7 @@ class pulse_data(parent_data): ...@@ -638,7 +623,7 @@ class pulse_data(parent_data):
result.append(last) result.append(last)
return result return result
def render_MW_and_custom(self, sample_rate, ref_channel_states): # @@@ Is this method used somewhere? def render_MW_and_custom(self, sample_rate, ref_channel_states): # @@@ Is this method used anywhere?
''' '''
Render MW pulses and custom data in 'rendered_elements'. Render MW pulses and custom data in 'rendered_elements'.
''' '''
...@@ -656,22 +641,22 @@ class pulse_data(parent_data): ...@@ -656,22 +641,22 @@ class pulse_data(parent_data):
ps_ch = phase_shifts_channels.setdefault(ps.channel_name, []) ps_ch = phase_shifts_channels.setdefault(ps.channel_name, [])
ps_ch.append(ps) ps_ch.append(ps)
for IQ_data_single_object in self.MW_pulse_data: for mw_pulse in self.MW_pulse_data:
# start stop time of MW pulse # start stop time of MW pulse
start_pulse = IQ_data_single_object.start start_pulse = mw_pulse.start
stop_pulse = IQ_data_single_object.stop stop_pulse = mw_pulse.stop
# max amp, freq and phase. # max amp, freq and phase.
amp = IQ_data_single_object.amplitude amp = mw_pulse.amplitude
freq = IQ_data_single_object.frequency freq = mw_pulse.frequency
phase = IQ_data_single_object.start_phase phase = mw_pulse.start_phase
if ref_channel_states and IQ_data_single_object.ref_channel in ref_channel_states.start_phase: if ref_channel_states and mw_pulse.ref_channel in ref_channel_states.start_phase:
ref_start_time = ref_channel_states.start_time ref_start_time = ref_channel_states.start_time
ref_start_phase = ref_channel_states.start_phase[IQ_data_single_object.ref_channel] ref_start_phase = ref_channel_states.start_phase[mw_pulse.ref_channel]
phase_shift = 0 phase_shift = 0
if IQ_data_single_object.ref_channel in phase_shifts_channels: if mw_pulse.ref_channel in phase_shifts_channels:
for ps in phase_shifts_channels[IQ_data_single_object.ref_channel]: for ps in phase_shifts_channels[mw_pulse.ref_channel]:
if ps.time <= start_pulse: if ps.time <= start_pulse:
phase_shift += ps.phase_shift phase_shift += ps.phase_shift
else: else:
...@@ -680,11 +665,11 @@ class pulse_data(parent_data): ...@@ -680,11 +665,11 @@ class pulse_data(parent_data):
phase_shift = 0 phase_shift = 0
# envelope data of the pulse # envelope data of the pulse
if IQ_data_single_object.envelope is None: if mw_pulse.envelope is None:
IQ_data_single_object.envelope = envelope_generator() mw_pulse.envelope = envelope_generator()
amp_envelope = IQ_data_single_object.envelope.get_AM_envelope((stop_pulse - start_pulse), sample_rate) amp_envelope = mw_pulse.envelope.get_AM_envelope((stop_pulse - start_pulse), sample_rate)
phase_envelope = IQ_data_single_object.envelope.get_PM_envelope((stop_pulse - start_pulse), sample_rate) phase_envelope = mw_pulse.envelope.get_PM_envelope((stop_pulse - start_pulse), sample_rate)
#self.baseband_pulse_data[-1,0] convert to point numbers #self.baseband_pulse_data[-1,0] convert to point numbers
n_pt = int((stop_pulse - start_pulse) * sample_rate) if isinstance(amp_envelope, float) else len(amp_envelope) n_pt = int((stop_pulse - start_pulse) * sample_rate) if isinstance(amp_envelope, float) else len(amp_envelope)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment