diff --git a/pulse_lib/segments/conditional_segment.py b/pulse_lib/segments/conditional_segment.py index cb991a73ee1565be599b58652b68c4d54d6c2c1b..f2158a0d72a552849a0bf190b07a954c966777a4 100644 --- a/pulse_lib/segments/conditional_segment.py +++ b/pulse_lib/segments/conditional_segment.py @@ -116,12 +116,9 @@ class conditional_segment: return comb_setpoints - def reset_time(self, extend_only = False): + def reset_time(self): ''' - Args: - extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...]. - - Allings all segments togeter and sets the input time to 0, + Alligns all segments togeter and sets the input time to 0, e.g. , chan1 : waveform until 70 ns chan2 : waveform until 140ns @@ -148,14 +145,14 @@ class conditional_segment: for branch in self.branches: for ch in branch.channels: - branch[ch].reset_time(loop_obj, False) + branch[ch].reset_time(loop_obj) def extend_dim(self, shape=None): for branch in self.branches: branch.extend_dim(shape) def enter_rendering_mode(self): - self.reset_time(False) + self.reset_time() for branch in self.branches: branch.enter_rendering_mode() diff --git a/pulse_lib/segments/data_classes/data_HVI_variables.py b/pulse_lib/segments/data_classes/data_HVI_variables.py index 19b135b9e9ac39c89dc7bfd79b452387fe07aeb9..afe2527fdaad3f7a878d2e449e7b3a20f002e432 100644 --- a/pulse_lib/segments/data_classes/data_HVI_variables.py +++ b/pulse_lib/segments/data_classes/data_HVI_variables.py @@ -50,7 +50,7 @@ class marker_HVI_variable(parent_data): else: self.my_amp_data[name] = amplitude - def reset_time(self, time = None, extend_only = False): + def reset_time(self, time = None): """ reset the effective start time. See online manual in pulse building instructions to understand this command. @@ -80,17 +80,6 @@ class marker_HVI_variable(parent_data): ''' return self.end_time - def slice_time(self, start, end): - """ - apply slice operation on this marker. - - Args: - start (double) : start time of the marker - stop (double) : stop time of the marker - """ - for key in self.my_time_data.keys(): - self.my_time_data[key] -= start - def get_vmin(self,sample_rate = 1e9): return 0 @@ -103,21 +92,14 @@ class marker_HVI_variable(parent_data): """ return 0 - def append(self, other, time = None): + def append(self, other): ''' Append two segments to each other, where the other segment is places after the first segment. Time is the total time of the first segment. Args: other (marker_HVI_variable) : other pulse data object to be appended - time (double/None) : length that the first segment should be. - - ** what to do with start time argument? ''' end_time = self.total_time - if time is not None: - end_time = time - self.slice_time(0, end_time) - other_shifted = other._shift_all_time(end_time) self.my_time_data.update(other_shifted.my_time_data) diff --git a/pulse_lib/segments/data_classes/data_acquisition.py b/pulse_lib/segments/data_classes/data_acquisition.py index a803a18e7610cd2c7c65b813300bc3c37b29e423..50b7b9fb08217c8297d84976154ba85a66846785 100644 --- a/pulse_lib/segments/data_classes/data_acquisition.py +++ b/pulse_lib/segments/data_classes/data_acquisition.py @@ -49,7 +49,7 @@ class acquisition_data(parent_data): if end_time > self.end_time: self.end_time = end_time - def reset_time(self, time = None, extend_only = False): + def reset_time(self, time = None): """ reset the effective start time. See online manual in pulse building instructions to understand this command. Args: @@ -78,35 +78,14 @@ class acquisition_data(parent_data): ''' return self.end_time - def slice_time(self, start, end): - """ - apply slice operation on this marker. - Args: - start (double) : start time of the marker - stop (double) : stop time of the marker - """ - sliced_data = [] - for data_item in self.data: - in_range, data_item = slice_out_acquisition(start, end, data_item) - if in_range == True: - sliced_data.append(data_item) - - self.data = sliced_data - self.end_time = end - start - - def append(self, other, time = None): + def append(self, other): ''' - Append two segments to each other, where the other segment is places after the first segment. - Time is the total time of the first segment. + Append two segments to each other, where the other segment is placed after the first segment. Args: other (acquisition_data) : other pulse data object to be appended - time (double/None) : length that the first segment should be. ''' end_time = self.end_time - if time is not None: - end_time = time - self.slice_time(0, end_time) other_shifted = other._shift_all_time(end_time) self.data += other_shifted.data @@ -212,26 +191,3 @@ class acquisition_data(parent_data): def round_pt(t, t_sample): return int(t / t_sample + 0.5) -def slice_out_acquisition(start, stop, data): - """ - check if start stop falls in valid range. - Args: - start (double) : startpoint of where the acquisition must be in - end (double) : endpoint where the acquisition must be in. - data (aquisition_data) : acquisition - Return: - True/False if start and stop are not in range - start_stop_position (tuple) : sliced time. - - Function also fixes the time in the pointer that is given. - """ - if data.start <= start or data.start >= stop: - return False - - result = copy.copy(data) - if result.start < start: - result.start = start - - result.start -= start - - return True, result diff --git a/pulse_lib/segments/data_classes/data_generic.py b/pulse_lib/segments/data_classes/data_generic.py index bfdd0dc0050057175b6e80b9bb6f91ec3b6a4cad..17cc99ce60262aa995ba13442e0cb77a41705569 100644 --- a/pulse_lib/segments/data_classes/data_generic.py +++ b/pulse_lib/segments/data_classes/data_generic.py @@ -40,39 +40,17 @@ class parent_data(ABC): cls.waveform_cache = LruCache(cls.waveform_cache.max_size) @abstractmethod - def append(): + def append(self): raise NotImplementedError() @abstractmethod - def slice_time(): + def reset_time(self, time = None): raise NotImplementedError() @abstractmethod - def reset_time(time = None, extend_only = False): + def wait(self, time): raise NotImplementedError() - @abstractmethod - def wait(time): - raise NotImplementedError() - -# @abstractmethod -# def get_vmax(self,sample_rate): -# ''' -# Calculate the maximum voltage in the current segment_single. -# Args: -# sample_rate (double) : rate at which is samples (in Hz) -# ''' -# raise NotImplemented -# -# @abstractmethod -# def get_vmin(self,sample_rate): -# ''' -# Calculate the maximum voltage in the current segment_single. -# Args: -# sample_rate (double) : rate at which is samples (in Hz) -# ''' -# raise NotImplemented - @abstractmethod def integrate_waveform(self, sample_rate): ''' diff --git a/pulse_lib/segments/data_classes/data_markers.py b/pulse_lib/segments/data_classes/data_markers.py index 8e9c89beb77ae41f06c4ec66fd564280137de8f6..3ac7ea9ebec36bf5698f3c928c25b974accd7afb 100644 --- a/pulse_lib/segments/data_classes/data_markers.py +++ b/pulse_lib/segments/data_classes/data_markers.py @@ -42,7 +42,7 @@ class marker_data(parent_data): if stop + self.start_time > self.end_time: self.end_time = self.start_time + stop - def reset_time(self, time = None, extend_only = False): + def reset_time(self, time = None): """ reset the effective start time. See online manual in pulse building instructions to understand this command. Args: @@ -71,23 +71,6 @@ class marker_data(parent_data): ''' return self.end_time - def slice_time(self, start, end): - """ - apply slice operation on this marker. - Args: - start (double) : start time of the marker - stop (double) : stop time of the marker - """ - sliced_maker_data = [] - for data_item in self.my_marker_data: - in_range, data_item = slice_out_marker_single(start, end, data_item) - if in_range == True: - sliced_maker_data.append(data_item) - - - self.my_marker_data = sliced_maker_data - self.end_time = end - start - def get_vmin(self,sample_rate = 1e9): return 0 @@ -100,19 +83,15 @@ class marker_data(parent_data): """ return 0 - def append(self, other, time = None): + def append(self, other): ''' Append two segments to each other, where the other segment is places after the first segment. Time is the total time of the first segment. Args: other (marker_data) : other pulse data object to be appended - time (double/None) : length that the first segment should be. ** what to do with start time argument? ''' end_time = self.end_time - if time is not None: - end_time = time - self.slice_time(0, end_time) other_shifted = other._shift_all_time(end_time) self.my_marker_data += other_shifted.my_marker_data @@ -206,30 +185,3 @@ class marker_data(parent_data): # TODO: add all pulses ?? return {} -def slice_out_marker_single(start, stop, start_stop_pulse): - """ - check if start stop falls in valid range. - Args: - start (double) : startpoint of where the marker must be in - end (double) : endpoint where the marker must be in. - start_stop_position (marker_pulse) : tuple iwht start and stop point of the marker. - Return: - True/False if start and stop are not in range - start_stop_position (tuple) : sliced time. - - Function also fixes the time in the pointer that is given. - """ - if start_stop_pulse.stop <= start or start_stop_pulse.start >= stop: - return False - - result = copy.copy(start_stop_pulse) - if result.start < start: - result.start = start - - if result.stop > stop: - result.stop = stop - - result.start -= start - result.stop -= start - - return True, result diff --git a/pulse_lib/segments/data_classes/data_pulse.py b/pulse_lib/segments/data_classes/data_pulse.py index e3a89831fa6f6ee87e82d24a9456d5cb76210791..44d7b4ceba6eb4c7ed99af306ee7397f78426791 100644 --- a/pulse_lib/segments/data_classes/data_pulse.py +++ b/pulse_lib/segments/data_classes/data_pulse.py @@ -195,7 +195,7 @@ class pulse_data(parent_data): ''' return self._end_time - def reset_time(self, time, extend_only = False): + def reset_time(self, time): ''' Preform a reset time on the current segment. Args: @@ -207,8 +207,7 @@ class pulse_data(parent_data): else: self._update_end_time(time) - if extend_only == False: - self.start_time = time + self.start_time = time def wait(self, time): """ @@ -219,19 +218,14 @@ class pulse_data(parent_data): """ self._end_time += time - def append(self, other, time = None): + def append(self, other): ''' - Append two segments to each other, where the other segment is places after the first segment. Time is the total time of the first segment. + Append two segments to each other, where the other segment is places after the first segment. Args: other (pulse_data) : other pulse data object to be appended - time (double/None) : length that the first segment should be. - ** what to do with start time argument? ''' - if time is None: - time = self.total_time - else: - self.slice_time(0, time) + time = self.total_time other_MW_pulse_data = copy.deepcopy(other.MW_pulse_data) shift_start_stop(other_MW_pulse_data, time) @@ -289,122 +283,6 @@ class pulse_data(parent_data): self._consolidated = False self._end_time = (n+1) * time - - def slice_time(self, start, end): - ''' - slice the pulse - Args: - Start (double) : enforced minimal starting time - End (double) : enforced max time - ''' - self.__slice_pulse_delta_data(start, end) - self.__slice_MW_data(start, end) - self.__slice_custom_pulse_data(start, end) - self.__slice_phase_shift_data(start, end) - - self._consolidated = False - self._end_time = end - start - - - ''' - details of pulse data methods - ''' - def __slice_MW_data(self, start, end): - ''' - slice MW_data - - Args: - start (double) : enforced minimal starting time - end (double) : enforced max time - ''' - new_MW_data = [] - - for i in self.MW_pulse_data: - if i.start < start: - i.start = start - if i.stop > end: - i.stop = end - - if i.start < i.stop: - i.start -= start - i.stop -= start - new_MW_data.append(i) - - self.MW_pulse_data = new_MW_data - - def __slice_custom_pulse_data(self, start, end): - ''' - slice custom_data - - Args: - start (double) : enforced minimal starting time - end (double) : enforced max time - ''' - new_custom_data = [] - - for i in self.custom_pulse_data: - if i.start < start: - i.start = start - if i.stop > end: - i.stop = end - - if i.start < i.stop: - i.start -= start - i.stop -= start - new_custom_data.append(i) - - self.custom_pulse_data = new_custom_data - - def __slice_phase_shift_data(self, start, end): - ''' - slice phase shift data - - Args: - start (double) : enforced minimal starting time - end (double) : enforced max time - ''' - new_phase_shifts = [] - - for i in self.phase_shifts: - if start <= i.time <= end: - new_phase_shifts.append(i) - - self.phase_shifts = new_phase_shifts - - def __slice_pulse_delta_data(self, start, end): - ''' - slice pulse delta data - - Args: - start (double) : enforced minimal starting time - end (double) : enforced max time - ''' - new_pulse_deltas = [] - - start_delta = pulse_delta(start, 0.0, 0.0) - end_delta = pulse_delta(end, 0.0, 0.0) - inf_delta = pulse_delta(np.inf, 0.0, 0.0) - - for entry in self.new_pulse_deltas: - if entry.time <= start: - start_delta.step += entry.step + (start-entry.time) * entry.ramp - start_delta.ramp += entry.ramp - elif entry.time < end: - new_pulse_deltas.append(entry) - elif entry.time != np.inf: - end_delta += entry - else: - inf_delta += entry - - if not start_delta.is_near_zero: - new_pulse_deltas.insert(0,start_delta) - if not end_delta.is_near_zero: - new_pulse_deltas.append(end_delta) - if not inf_delta.is_near_zero: - new_pulse_deltas.append(inf_delta) - - self.pulse_deltas = new_pulse_deltas - def shift_MW_frequency(self, frequency): ''' shift the frequency of a MW signal that is defined. This is needed for dealing with the upconverion of a IQ signal. diff --git a/pulse_lib/segments/segment_HVI_variables.py b/pulse_lib/segments/segment_HVI_variables.py index 991a411cab1d3a778e0070303ea6c3e98f2ba49b..98860fac123c851543f2de29f5e4730a2bab7d3b 100644 --- a/pulse_lib/segments/segment_HVI_variables.py +++ b/pulse_lib/segments/segment_HVI_variables.py @@ -2,7 +2,7 @@ Marker implementation. """ -from pulse_lib.segments.segment_base import segment_base, last_edited +from pulse_lib.segments.segment_base import segment_base from pulse_lib.segments.utility.data_handling_functions import loop_controller, loop_controller_post_processing from pulse_lib.segments.data_classes.data_HVI_variables import marker_HVI_variable import numpy as np @@ -20,7 +20,6 @@ class segment_HVI_variables(segment_base): super(segment_HVI_variables, self).__init__(name, marker_HVI_variable(), segment_type = 'render') self._data_hvi_variable = None - @last_edited @loop_controller def _add_HVI_variable(self, name, value, time): """ @@ -88,7 +87,6 @@ if __name__ == '__main__': # print("maximal voltage (mV) : ", s1.v_max([0])) # print("integral of data (always 0 for markers) : " ,s1.integrate([0])) # print("memory location of render data : " ,s1.pulse_data_all) - # print("Last edited : " ,s1.last_edit) # print("Shape :" ,s1.shape) # s1.plot_segment() diff --git a/pulse_lib/segments/segment_IQ.py b/pulse_lib/segments/segment_IQ.py index 33f5fa6851232d2c965ac41edbde937fca0f095c..84479285edf7d30fc2b237be63f633afa96b89f0 100644 --- a/pulse_lib/segments/segment_IQ.py +++ b/pulse_lib/segments/segment_IQ.py @@ -20,7 +20,7 @@ TODO : change dicts to keep the data to an object!! import numpy as np import copy -from pulse_lib.segments.segment_base import last_edited, segment_base +from pulse_lib.segments.segment_base import segment_base from pulse_lib.segments.utility.data_handling_functions import loop_controller, update_dimension from pulse_lib.segments.data_classes.data_pulse import pulse_data, PhaseShift from pulse_lib.segments.data_classes.data_IQ import envelope_generator, IQ_data_single, make_chirp @@ -59,13 +59,11 @@ class segment_IQ(segment_base): self.data_tmp.global_phase += phase return self.data_tmp - @last_edited @loop_controller def add_phase_shift(self, t, phase): self.data_tmp.add_phase_shift(PhaseShift(t + self.data_tmp.start_time, phase, self.name)) return self.data_tmp - @last_edited @loop_controller def add_MW_pulse(self, t0, t1, amp, freq, phase = 0, AM = None, PM = None): ''' @@ -89,7 +87,6 @@ class segment_IQ(segment_base): self.data_tmp.add_MW_data(MW_data) return self.data_tmp - @last_edited @loop_controller def add_chirp(self, t0, t1, f0, f1, amp): ''' diff --git a/pulse_lib/segments/segment_acquisition.py b/pulse_lib/segments/segment_acquisition.py index cb87087a9cb5e1f027c1f45fb282f34e2765a850..6698350046787c841d3942341e55d7ed84415897 100644 --- a/pulse_lib/segments/segment_acquisition.py +++ b/pulse_lib/segments/segment_acquisition.py @@ -98,14 +98,13 @@ class segment_acquisition(): return segment_acquisition(self.name, self._measurement_segment) @loop_controller - def reset_time(self, time=None, extend_only = False): + def reset_time(self, time=None): ''' resets the time back to zero after a certain point Args: time (double) : (optional), after time to reset back to 0. Note that this is absolute time and not rescaled time. - extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...]. ''' - self.data_tmp.reset_time(time, extend_only) + self.data_tmp.reset_time(time) return self.data_tmp @loop_controller @@ -147,20 +146,18 @@ class segment_acquisition(): item.data = data_item return item - def append(self, other, time = None): + def append(self, other): ''' Put the other segment behind this one. Args: other (segment_single) : the segment to be appended - time (double/loop_obj) : attach at the given time (if None, append at total_time of the segment) A time reset will be done after the other segment is added. - TODO: transfer of units ''' other_loopobj = loop_obj() other_loopobj.add_data(other.data, axis=list(range(other.data.ndim -1,-1,-1))) self._setpoints += other._setpoints - self.__append(other_loopobj, time) + self.__append(other_loopobj) return self @@ -189,43 +186,15 @@ class segment_acquisition(): ''' return self.data_tmp - - @loop_controller - def __append(self, other, time): + def __append(self, other): """ Put the other segment behind this one (for single segment data object) Args: other (segment_single) : the segment to be appended - time (double/loop_obj) : attach at the given time (if None, append at total_time of the segment) - """ - if time is None: - time = self.data_tmp.total_time - - - self.data_tmp.append(other, time) - return self.data_tmp - - @loop_controller - def slice_time(self, start_time, stop_time): - """ - Cuts parts out of a segment. - - Args: - start_time (double) : effective new start time - stop_time (double) : new ending time of the segment - - The slice_time function allows you to cut a waveform in different sizes. - This function should be handy for debugging, example usage would be, - You are runnning an algorithm and want to check what the measurement outcomes are though the whole algorithm. - Pratically, you want to know - 0 -> 10ns (@10 ns still everything as expected?) - 0 -> 20ns - 0 -> ... - This function would allow you to do that, e.g. by calling segment.cut_segment(0, lp.linspace(10,100,9)) """ - self.data_tmp.slice_time(start_time, stop_time) + self.data_tmp.append(other) return self.data_tmp # ==== getters on all_data diff --git a/pulse_lib/segments/segment_base.py b/pulse_lib/segments/segment_base.py index 86f8ced59a2d5e8bae4b725347777448d7e52fee..a34f3b44267ae5bbcf9295f9e19f100c53dabb4e 100644 --- a/pulse_lib/segments/segment_base.py +++ b/pulse_lib/segments/segment_base.py @@ -11,30 +11,9 @@ from pulse_lib.segments.utility.looping import loop_obj from pulse_lib.segments.utility.setpoint_mgr import setpoint_mgr from pulse_lib.segments.data_classes.data_generic import map_index -from functools import wraps import copy - -def last_edited(f): - ''' - just a simpe decorater used to say that a certain wavefrom is updaded and therefore a new upload needs to be made to the awg. - ''' - @wraps(f) - def wrapper(*args, **kwargs): - if args[0].render_mode == True: - ValueError("cannot alter this segment, this segment ({}) in render mode.".format(args[0].name)) - args[0]._last_edit = last_edit.ToRender - return f(*args, **kwargs) - return wrapper - -class last_edit: - """ - spec of what the state is of the pulse. - """ - ToRender = -1 - Rendered = 0 - class segment_base(): ''' Class defining base function of a segment. All segment types should support all operators. @@ -54,7 +33,6 @@ class segment_base(): self.name = name self.render_mode = False # variable specifing the laetest change to the waveforms, - self._last_edit = last_edit.ToRender # store data in numpy looking object for easy operator access. self.data = data_container(data_object) @@ -90,19 +68,16 @@ class segment_base(): return cpy - @last_edited @loop_controller - def reset_time(self, time=None, extend_only = False): + def reset_time(self, time=None): ''' resets the time back to zero after a certain point Args: time (double) : (optional), after time to reset back to 0. Note that this is absolute time and not rescaled time. - extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...]. ''' - self.data_tmp.reset_time(time, extend_only) + self.data_tmp.reset_time(time) return self.data_tmp - @last_edited @loop_controller def wait(self, time, reset_time=False): ''' @@ -158,9 +133,6 @@ class segment_base(): return new_segment - def __truediv__(self, other): - raise NotImplemented - def __getitem__(self, *key): ''' get slice or single item of this segment (note no copying, just referencing) @@ -188,8 +160,7 @@ class segment_base(): item._data_hvi_variable = item.data return item - @last_edited - def append(self, other, time = None): + def append(self, other): ''' Put the other segment behind this one. Args: @@ -202,11 +173,10 @@ class segment_base(): other_loopobj = loop_obj() other_loopobj.add_data(other.data, axis=list(range(other.data.ndim -1,-1,-1))) self._setpoints += other._setpoints - self.__append(other_loopobj, time) + self.__append(other_loopobj) return self - @last_edited @loop_controller def repeat(self, number): ''' @@ -272,41 +242,14 @@ class segment_base(): self._data_hvi_variable._add_HVI_variable(marker_name, value, time) @loop_controller - def __append(self, other, time): + def __append(self, other): """ Put the other segment behind this one (for single segment data object) Args: other (segment_single) : the segment to be appended - time (double/loop_obj) : attach at the given time (if None, append at total_time of the segment) - """ - if time is None: - time = self.data_tmp.total_time - - - self.data_tmp.append(other, time) - return self.data_tmp - - @last_edited - @loop_controller - def slice_time(self, start_time, stop_time): """ - Cuts parts out of a segment. - - Args: - start_time (double) : effective new start time - stop_time (double) : new ending time of the segment - - The slice_time function allows you to cut a waveform in different sizes. - This function should be handy for debugging, example usage would be, - You are runnning an algorithm and want to check what the measurement outcomes are though the whole algorithm. - Pratically, you want to know - 0 -> 10ns (@10 ns still everything as expected?) - 0 -> 20ns - 0 -> ... - This function would allow you to do that, e.g. by calling segment.cut_segment(0, lp.linspace(10,100,9)) - """ - self.data_tmp.slice_time(start_time, stop_time) + self.data_tmp.append(other) return self.data_tmp # ==== getters on all_data @@ -317,14 +260,13 @@ class segment_base(): ''' pulse data object that contains the counted op data of all the reference channels (e.g. IQ and virtual gates). ''' - if self.last_edit == last_edit.ToRender or self._pulse_data_all is None: + if self._pulse_data_all is None: self._pulse_data_all = copy.copy(self.data) for ref_chan in self.reference_channels: # make sure both have the same size. my_shape = find_common_dimension(self._pulse_data_all.shape, ref_chan.segment.shape) self._pulse_data_all = update_dimension(self._pulse_data_all, my_shape) self._pulse_data_all += ref_chan.segment.pulse_data_all*ref_chan.multiplication_factor - ref_chan.segment._last_edit = last_edit.Rendered for ref_chan in self.IQ_ref_channels: my_shape = find_common_dimension(self._pulse_data_all.shape, ref_chan.virtual_channel.shape) self._pulse_data_all = update_dimension(self._pulse_data_all, my_shape) @@ -334,8 +276,6 @@ class segment_base(): self._pulse_data_all = update_dimension(self._pulse_data_all, my_shape) self._pulse_data_all += ref_chan.IQ_channel_ptr.get_marker_data() - self._last_edit = last_edit.Rendered - return self._pulse_data_all @property @@ -440,20 +380,6 @@ class segment_base(): plt.ylabel("amplitude (mV)") plt.legend() - @property - def last_edit(self): - for i in self.reference_channels: - if i.segment._last_edit == last_edit.ToRender: - self._last_edit = last_edit.ToRender - for i in self.IQ_ref_channels: - if i.virtual_channel == last_edit.ToRender: - self._last_edit = last_edit.ToRender - for i in self.references_markers: - if i.IQ_channel_ptr == last_edit.ToRender: - self._last_edit = last_edit.ToRender - - return self._last_edit - def get_metadata(self): # Uses highest index of sequencer array (data_tmp) return self.data_tmp.get_metadata(self.name) diff --git a/pulse_lib/segments/segment_container.py b/pulse_lib/segments/segment_container.py index 40eee22a6a933768e5a6d9fb8dd9183f04e64184..844f7f44a8a0561a44ed5274f42d3a9744091066 100644 --- a/pulse_lib/segments/segment_container.py +++ b/pulse_lib/segments/segment_container.py @@ -17,7 +17,6 @@ from pulse_lib.segments.data_classes.data_generic import map_index import uuid import numpy as np -import datetime import copy from dataclasses import dataclass @@ -47,7 +46,6 @@ class segment_container(): self.render_mode = False self._total_times = None self.id = uuid.uuid4() - self._Vmin_max_data = dict() self._software_markers = segment_HVI_variables("HVI_markers") self._segment_measurements = segment_measurements() @@ -57,12 +55,6 @@ class segment_container(): self.name = name self.sample_rate = sample_rate - for name in channel_names: - self._Vmin_max_data[name] = {"v_min" : None, "v_max" : None} - - self.prev_upload = datetime.datetime.utcfromtimestamp(0) - - # define real channels (+ markers) for name in channel_names: setattr(self, name, segment_pulse(name, self._software_markers)) @@ -118,7 +110,6 @@ class segment_container(): setattr(new, chan_name,new_chan) new.render_mode = copy.copy(self.render_mode) - new._Vmin_max_data = copy.copy(self._Vmin_max_data) new._software_markers =self._software_markers[index] new._setpoints = self._setpoints @@ -143,7 +134,6 @@ class segment_container(): setattr(new, chan_name,new_chan) new.render_mode = copy.copy(self.render_mode) - new._Vmin_max_data = copy.copy(self._Vmin_max_data) new._software_markers = copy.copy(self._software_markers) new._segment_measurements = copy.copy(self._segment_measurements) new._setpoints = copy.copy(self._setpoints) @@ -202,14 +192,6 @@ class segment_container(): def ndim(self): return len(self.shape) - @property - def last_mod(self): - time = datetime.datetime.utcfromtimestamp(0) - for i in self.channels: - if getattr(self, i).last_edit > time: - time = getattr(self, i).last_edit - return time - @property def total_time(self): ''' @@ -271,63 +253,7 @@ class segment_container(): return comb_setpoints - - @property - def Vmin_max_data(self): - if self.prev_upload < self.last_mod: - - for i in range(len(self.channels)): - self._Vmin_max_data[self.channels[i]]['v_min'] = getattr(self,self.channels[i]).v_min - self._Vmin_max_data[self.channels[i]]['v_max'] = getattr(self,self.channels[i]).v_max - - return self._Vmin_max_data - - def append(self, other, time=None): - ''' - append other segments the the current ones in the container. - Args: - other (segment_container) : other segment to append - ''' - if not isinstance(other, segment_container): - raise TypeError("segment_container object expected. Did you supply a single segment?") - - # make sure all object have a full size. - my_shape = find_common_dimension(self.shape, other.shape) - other.extend_dim(my_shape) - self.extend_dim(my_shape) - - self._setpoints += other._setpoints - - if time == None: - times = self.total_time - - time = lp.loop_obj(no_setpoints=True) - time.add_data(times, list(range(len(times.shape)-1, -1,-1))) - for i in self.channels: - segment = getattr(self, i) - segment.append(getattr(other, i), time) - - def slice_time(self, start, stop): - """ - slice time in a segment container - Args: - start (double) : start time of the slice - stop (double) : stop time of the slice - - The slice_time function allows you to cut all the waveforms in the segment container in different sizes. - This function should be handy for debugging, example usage would be, - You are runnning an algorithm and want to check what the measurement outcomes are though the whole algorithm. - Pratically, you want to know - 0 -> 10ns (@10 ns still everything as expected?) - 0 -> 20ns - 0 -> ... - This function would allow you to do that, e.g. by calling segment_container.cut_segment(0, lp.linspace(10,100,9)) - """ - for i in self.channels: - segment = getattr(self, i) - segment.slice_time(start, stop) - - def reset_time(self, extend_only = False): + def reset_time(self): ''' Args: extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...]. @@ -339,25 +265,33 @@ class segment_container(): -> totaltime will be 140 ns, when you now as a new pulse (e.g. at time 0, it will actually occur at 140 ns in both blocks) ''' - - n_channels = len(self.channels) shape = list(self.shape) - time_data = np.empty([n_channels] + shape) - for i in range(len(self.channels)): - time_data[i] = upconvert_dimension(getattr(self, self.channels[i]).total_time, shape) - - times = np.amax(time_data, axis = 0) - times, axis = reduce_arr(times) - if len(axis) == 0: - loop_obj = times + if shape != [1]: + n_channels = len(self.channels) + time_data = np.empty([n_channels] + shape) + for i,channel in enumerate(self.channels): + time_data[i] = upconvert_dimension(self[channel].total_time, shape) + + times = np.amax(time_data, axis = 0) + times, axis = reduce_arr(times) + if len(axis) == 0: + loop_obj = times + else: + loop_obj = lp.loop_obj(no_setpoints=True) + loop_obj.add_data(times, axis) + + for channel in self.channels: + segment = self[channel] + segment.reset_time(loop_obj) else: - loop_obj = lp.loop_obj(no_setpoints=True) - loop_obj.add_data(times, axis) + time = 0 + for channel in self.channels: + time = max(time, self[channel].total_time[0]) + for channel in self.channels: + segment = self[channel] + segment.reset_time(time) - for i in self.channels: - segment = getattr(self, i) - segment.reset_time(loop_obj, False) def get_waveform(self, channel, index = [0], sample_rate=1e9, ref_channel_states=None): ''' diff --git a/pulse_lib/segments/segment_markers.py b/pulse_lib/segments/segment_markers.py index 79fab669e61d892fa9063eeda862c2b15b02ee78..7ba237e2cf57840f3620bf7102744282ed1ad297 100644 --- a/pulse_lib/segments/segment_markers.py +++ b/pulse_lib/segments/segment_markers.py @@ -2,7 +2,7 @@ Marker implementation. """ -from pulse_lib.segments.segment_base import segment_base, last_edited +from pulse_lib.segments.segment_base import segment_base from pulse_lib.segments.segment_IQ import segment_IQ from pulse_lib.segments.utility.data_handling_functions import loop_controller from pulse_lib.segments.data_classes.data_markers import marker_data @@ -26,7 +26,6 @@ class segment_marker(segment_base): """ super(segment_marker, self).__init__(name, marker_data(), HVI_variable_data, segment_type = 'render') - @last_edited @loop_controller def add_marker(self, start, stop): """ @@ -67,7 +66,6 @@ if __name__ == '__main__': print("maximal voltage (mV) : ", s1.v_max([0])) print("integral of data (always 0 for markers) : " ,s1.integrate([0])) print("memory location of render data : " ,s1.pulse_data_all) - print("Last edited : " ,s1.last_edit) print("Shape :" ,s1.shape) s1.plot_segment() diff --git a/pulse_lib/segments/segment_pulse.py b/pulse_lib/segments/segment_pulse.py index f9763f5fdfc673271a06a1a828caa5890f09dda1..7a7de3a39fe7124bcb93b3ac2a3d0aa1b41f486f 100644 --- a/pulse_lib/segments/segment_pulse.py +++ b/pulse_lib/segments/segment_pulse.py @@ -4,7 +4,7 @@ Class that is used to make DC pulses. import numpy as np from pulse_lib.configuration.iq_channels import IQ_out_channel_info -from pulse_lib.segments.segment_base import last_edited, segment_base +from pulse_lib.segments.segment_base import segment_base from pulse_lib.segments.utility.data_handling_functions import loop_controller from pulse_lib.segments.data_classes.data_pulse import pulse_data, custom_pulse_element, pulse_delta from pulse_lib.segments.data_classes.data_IQ import IQ_data_single @@ -33,7 +33,6 @@ class segment_pulse(segment_base): super().__init__(name, pulse_data(), HVI_variable_data,segment_type) - @last_edited @loop_controller def add_block(self,start,stop, amplitude): ''' @@ -45,7 +44,6 @@ class segment_pulse(segment_base): step=-amplitude)) return self.data_tmp - @last_edited @loop_controller def add_ramp(self, start, stop, amplitude, keep_amplitude=False): ''' @@ -58,7 +56,6 @@ class segment_pulse(segment_base): ''' return self._add_ramp(start, stop, 0, amplitude, keep_amplitude) - @last_edited @loop_controller def add_ramp_ss(self, start, stop, start_amplitude, stop_amplitude, keep_amplitude=False): ''' @@ -103,7 +100,6 @@ class segment_pulse(segment_base): return self.data_tmp - @last_edited @loop_controller def wait(self, wait): ''' @@ -114,7 +110,6 @@ class segment_pulse(segment_base): self.data_tmp.wait(wait) return self.data_tmp - @last_edited @loop_controller def add_sin(self, start, stop, amp, freq, phase_offset=0): ''' @@ -136,7 +131,6 @@ class segment_pulse(segment_base): return self.data_tmp - @last_edited @loop_controller def add_custom_pulse(self, start, stop, amplitude, custom_func, **kwargs): """ @@ -182,7 +176,6 @@ class segment_pulse(segment_base): ''' self.IQ_ref_channels.append(IQ_render_info(virtual_channel, out_channel)) - @last_edited @loop_controller def repeat(self, number): ''' diff --git a/pulse_lib/segments/utility/data_handling_functions.py b/pulse_lib/segments/utility/data_handling_functions.py index 773bb867e0e6f8a79324827eb51ca1944c7cfe2a..90130ba85acec9123045661dddd5a6c7297e06ff 100644 --- a/pulse_lib/segments/utility/data_handling_functions.py +++ b/pulse_lib/segments/utility/data_handling_functions.py @@ -497,10 +497,14 @@ def reduce_arr(arr): reduced array(np.ndarray) : array with reduced data. data_axis (list) : the axises that have changing data. """ - ndim = len(arr.shape) + shape = arr.shape + ndim = len(shape) data_axis = [] slice_array = () for i in range(ndim): + if shape[i] == 1: + slice_array += (0,) + continue mn = np.min(arr, axis=i) mx = np.max(arr, axis=i) eq = np.all(mn == mx) diff --git a/pulse_lib/sequencer.py b/pulse_lib/sequencer.py index dcbffd05a5e74d90c495942267ae8753d8ec886f..2c9d2c8fdebd601eacb60c5d08280a9833d531cd 100644 --- a/pulse_lib/sequencer.py +++ b/pulse_lib/sequencer.py @@ -753,8 +753,6 @@ if __name__ == '__main__': b.add_HVI_variable("my_vatr", 800) a.a.add_block(20,lp.linspace(50,100,10, axis = 1, name = "time", unit = "ns"),100) - b.slice_time(0,lp.linspace(80,100,10, name = "time", unit = "ns", axis= 2)) - my_seq = [a,b] seq = sequencer(None, dict())