diff --git a/exopy_pulses/pulses/shapes/gaussian_shape.py b/exopy_pulses/pulses/shapes/gaussian_shape.py index 5b65232..85dc849 100644 --- a/exopy_pulses/pulses/shapes/gaussian_shape.py +++ b/exopy_pulses/pulses/shapes/gaussian_shape.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2018 by ExopyPulses Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyPulses Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # @@ -25,6 +25,8 @@ class GaussianShape(AbstractShape): """ #: Amplitude of the pulse this should be a number between -1.0 and 1.0 amplitude = Str('1.0').tag(pref=True, feval=Feval(types=Real)) + + #: Sigma of gaussian pulse, units are AWG context units sigma = Str('10.0').tag(pref=True, feval=Feval(types=Real)) def eval_entries(self, root_vars, sequence_locals, missing, errors): diff --git a/exopy_pulses/pulses/shapes/tanh_shape.py b/exopy_pulses/pulses/shapes/tanh_shape.py index a53512d..dc45f4a 100644 --- a/exopy_pulses/pulses/shapes/tanh_shape.py +++ b/exopy_pulses/pulses/shapes/tanh_shape.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2018 by ExopyPulses Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyPulses Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # @@ -20,11 +20,13 @@ class TanhShape(AbstractShape): - """ Atan pulse with a variable amplitude and sigma. + """ Tanh pulse with a variable amplitude and sigma. """ #: Amplitude of the pulse this should be a number between -1.0 and 1.0 amplitude = Str('1.0').tag(pref=True, feval=Feval(types=Real)) + + #: Sigma of tanh pulse, basically raising time, units are AWG context units sigma = Str('10.0').tag(pref=True, feval=Feval(types=Real)) def eval_entries(self, root_vars, sequence_locals, missing, errors): diff --git a/exopy_pulses/pulses/shapes/views/gaussian_shape_view.enaml b/exopy_pulses/pulses/shapes/views/gaussian_shape_view.enaml index e6d5140..2f0ace0 100644 --- a/exopy_pulses/pulses/shapes/views/gaussian_shape_view.enaml +++ b/exopy_pulses/pulses/shapes/views/gaussian_shape_view.enaml @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2018 by ExopyPulses Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyPulses Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # diff --git a/exopy_pulses/pulses/shapes/views/tanh_shape_view.enaml b/exopy_pulses/pulses/shapes/views/tanh_shape_view.enaml index 705b8b0..6e74e71 100644 --- a/exopy_pulses/pulses/shapes/views/tanh_shape_view.enaml +++ b/exopy_pulses/pulses/shapes/views/tanh_shape_view.enaml @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2018 by ExopyPulses Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyPulses Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # diff --git a/exopy_pulses/tasks/tasks/instrs/transfer_pulse_loop_task.py b/exopy_pulses/tasks/tasks/instrs/transfer_pulse_loop_task.py index 8af513d..a0c0ef8 100644 --- a/exopy_pulses/tasks/tasks/instrs/transfer_pulse_loop_task.py +++ b/exopy_pulses/tasks/tasks/instrs/transfer_pulse_loop_task.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2016 by ExopyHqcLegacy Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyHqcLegacy Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # @@ -25,7 +25,6 @@ class TransferPulseLoopTask(InstrumentTask): """Build and transfer a pulse sequence to an instrument. """ - #: Sequence path for the case of sequence simply referenced. sequence_path = Str().tag(pref=True) @@ -38,9 +37,14 @@ class TransferPulseLoopTask(InstrumentTask): #: Global variable to use for the sequence. sequence_vars = Typed(OrderedDict, ()).tag(pref=(ordered_dict_to_pref, ordered_dict_from_pref)) - + #: operation mode of the awg - operation = Enum('Clean, Load & Enqueue', 'Clean & Load', 'Load', 'Load & Enqueue all').tag(pref=True) + operation = Enum( + 'Clean, Load & Enqueue', + 'Clean & Load', + 'Load', + 'Load & Enqueue all').tag( + pref=True) #: Loop variables: channels on which the loop will be done, loop parameters #: names, start value, stop value and number of points per loop @@ -50,55 +54,55 @@ class TransferPulseLoopTask(InstrumentTask): loop_stop = Str('0').tag(pref=True) loop_points = Str('2').tag(pref=True) - + #: run mode of the awg run_mode = Enum('Ext Trig', 'Int Trig', 'Continuous').tag(pref=True) #: Internal trigger period in mus trigger_period = Str('20').tag(pref=True) - + parameters = Typed(OrderedDict, ()).tag(pref=[ordered_dict_to_pref, - ordered_dict_from_pref]) - + ordered_dict_from_pref]) + database_entries = set_default({'num_loop': 1}) -# def check(self, *args, **kwargs): -# """Check that the sequence can be compiled. -# -# """ -# test, traceback = super(TransferPulseLoopTask, -# self).check(*args, **kwargs) -# err_path = self.path + '/' + self.name + '-' -# -# msg = 'Failed to evaluate {} ({}): {}' -# seq = self.sequence -# for k, v in self.sequence_vars.items(): -# try: -# seq.external_vars[k] = self.format_and_eval_string(v) -# except Exception: -# test = False -# traceback[err_path+k] = msg.format(k, v, format_exc()) -# -# if not test: -# return test, traceback -# -# context = seq.context -# res, infos, errors = context.compile_and_transfer_sequence(seq) -# -# if not res: -# traceback[err_path+'compil'] = errors -# return False, traceback -# -# for k, v in infos.items(): -# self.write_in_database(k, v) -# -# if self.sequence_path: -# if not (self.sequence_timestamp == -# os.path.getmtime(self.sequence_path)): -# msg = 'The sequence is outdated, consider refreshing it.' -# traceback[err_path+'outdated'] = msg -# -# return test, traceback + def check(self, *args, **kwargs): + """Check that the sequence can be compiled. + + """ + test, traceback = super(TransferPulseLoopTask, + self).check(*args, **kwargs) + err_path = self.path + '/' + self.name + '-' + + msg = 'Failed to evaluate {} ({}): {}' + seq = self.sequence + for k, v in self.sequence_vars.items(): + try: + seq.external_vars[k] = self.format_and_eval_string(v) + except Exception: + test = False + traceback[err_path + k] = msg.format(k, v, format_exc()) + + if not test: + return test, traceback + + context = seq.context + res, infos, errors = context.compile_and_transfer_sequence(seq) + + if not res: + traceback[err_path + 'compil'] = errors + return False, traceback + + for k, v in infos.items(): + self.write_in_database(k, v) + + if self.sequence_path: + if not (self.sequence_timestamp == + os.path.getmtime(self.sequence_path)): + msg = 'The sequence is outdated, consider refreshing it.' + traceback[err_path + 'outdated'] = msg + + return test, traceback def perform(self): """Compile the sequence. @@ -107,35 +111,31 @@ def perform(self): operation = self.operation seq = self.sequence context = seq.context - if self.run_mode=='Int Trig': + if self.run_mode == 'Int Trig': internal_trigger = True - else: + else: internal_trigger = False self.driver.internal_trigger = internal_trigger if internal_trigger: - self.driver.internal_trigger_period = int(float(self.trigger_period) * 1000) - + self.driver.internal_trigger_period = int( + float(self.trigger_period) * 1000) + self.driver.clear_all_sequences() if operation in ['Clean, Load & Enqueue', 'Clean & Load']: self.driver.delete_all_waveforms() first_index = 1 -# print("First index shoud be %d"%first_index) else: n_remaining_wf = self.driver.get_waveform_number() -# print('Remaining of waveforms = '+str(n_remaining_wf)) - last_wf = str(self.driver.get_waveform_name(n_remaining_wf-1)) + last_wf = str(self.driver.get_waveform_name(n_remaining_wf - 1)) last_wf = last_wf.split('_') - first_index = int(last_wf[1])+1 -# print("First index shoud be %d"%first_index) + first_index = int(last_wf[1]) + 1 _used_channels = [] - loops = [] name_parameters = [] n_loops = len(self.parameters) -# print(n_loops) - if n_loops>0: + if n_loops > 0: context.run_after_transfer = False context.select_after_transfer = False self.driver.run_mode = 'SEQUENCE' @@ -145,72 +145,82 @@ def perform(self): loop_points = int(self.format_and_eval_string(params[1][2])) loops.append(np.linspace(loop_start, loop_stop, loop_points)) name_parameters.append(params[0]) - self.write_in_database(params[0]+'_loop', np.linspace(loop_start, loop_stop, loop_points)) - - loop_values = np.moveaxis(np.array(np.meshgrid(*loops)),0,-1).reshape((-1,n_loops)) - if operation=='Clean, Load & Enqueue': + self.write_in_database( + params[0] + '_loop', + np.linspace( + loop_start, + loop_stop, + loop_points)) + + loop_values = np.moveaxis( + np.array(np.meshgrid(*loops)), 0, -1).reshape((-1, n_loops)) + if operation == 'Clean, Load & Enqueue': self.write_in_database('num_loop', len(loop_values)) for nn, loop_value in enumerate(loop_values): for ii, name_parameter in enumerate(name_parameters): self.write_in_database(name_parameter, loop_value[ii]) for k, v in self.sequence_vars.items(): seq.external_vars[k] = self.format_and_eval_string(v) - context.sequence_name = '{}_{}'.format('', nn+first_index) + context.sequence_name = '{}_{}'.format('', nn + first_index) res, infos, errors = context.compile_and_transfer_sequence( - seq, - driver=self.driver) - if operation=='Clean, Load & Enqueue': + seq, + driver=self.driver) + if operation == 'Clean, Load & Enqueue': for cc in range(4): - _seq = 'sequence_ch'+str(cc+1) + _seq = 'sequence_ch' + str(cc + 1) if infos[_seq]: - self.driver.get_channel(cc+1).set_sequence_pos(infos[_seq], - nn+1) - _used_channels.append(cc+1) - self.driver.set_jump_pos(nn+1, 1) + self.driver.get_channel( + cc + + 1).set_sequence_pos( + infos[_seq], + nn + + 1) + _used_channels.append(cc + 1) + self.driver.set_jump_pos(nn + 1, 1) self.driver.set_goto_pos(len(loop_values), 1) for cc in set(_used_channels): self.driver.get_channel(cc).output_state = 'on' - + if not res: raise Exception('Failed to compile sequence :\n' + pformat(errors)) self.write_in_database(name_parameter, loop_value[ii]) - + else: for k, v in self.sequence_vars.items(): seq.external_vars[k] = self.format_and_eval_string(v) - if self.run_mode=='Continuous': + if self.run_mode == 'Continuous': self.driver.run_mode = 'CONT' else: self.driver.run_mode = 'TRIG' context.sequence_name = '{}_{}'.format('', first_index) - res, infos, errors = context.compile_and_transfer_sequence(seq, - self.driver) + res, infos, errors = context.compile_and_transfer_sequence( + seq, self.driver) if not res: raise Exception('Failed to compile sequence :\n' + pformat(errors)) - + for k, v in infos.items(): self.write_in_database(k, v) - - if operation=='Load & Enqueue all': - n_wf = self.driver.get_waveform_number()-25 + + if operation == 'Load & Enqueue all': + n_wf = self.driver.get_waveform_number() - 25 channels_to_turn_on = set() for ii in range(n_wf): - index = ii+25 + index = ii + 25 current_wf = str(self.driver.get_waveform_name(index)) current_ch = int(current_wf[-1]) - current_index = int(current_wf.split('_')[1]) + current_index = int(current_wf.split('_')[1]) channels_to_turn_on.add(current_ch) - self.driver.get_channel(current_ch).set_sequence_pos(current_wf, - current_index) + self.driver.get_channel(current_ch).set_sequence_pos( + current_wf, current_index) self.driver.set_jump_pos(current_index, 1) self.driver.set_goto_pos(current_index, 1) self.write_in_database('num_loop', current_index) for cc in channels_to_turn_on: self.driver.get_channel(cc).output_state = 'on' - + def register_preferences(self): """Register the task preferences into the preferences system. @@ -270,7 +280,7 @@ def _post_setattr_sequence(self, old, new): if entries != self.database_entries: self.database_entries = entries - + def _post_setattr_parameters(self, old, new): """Observer keeping the database entries in sync with the declared definitions. @@ -279,10 +289,10 @@ def _post_setattr_parameters(self, old, new): entries = self.database_entries.copy() for e in old: del entries[e] - del entries[e+'_loop'] + del entries[e + '_loop'] for e in new: entries.update({key: 0.0 for key in new}) - entries.update({key+'_loop': 0.0 for key in new}) + entries.update({key + '_loop': 0.0 for key in new}) self.database_entries = entries def _update_database_entries(self, change): diff --git a/exopy_pulses/tasks/tasks/instrs/transfer_sequence_task.py b/exopy_pulses/tasks/tasks/instrs/transfer_sequence_task.py index 0fb766a..c8dea69 100644 --- a/exopy_pulses/tasks/tasks/instrs/transfer_sequence_task.py +++ b/exopy_pulses/tasks/tasks/instrs/transfer_sequence_task.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- -# Copyright 2015-2018 by ExopyHqcLegacy Authors, see AUTHORS for more details. +# Copyright 2015-2021 by ExopyHqcLegacy Authors, see AUTHORS for more details. # # Distributed under the terms of the BSD license. # @@ -37,7 +37,7 @@ class TransferPulseSequenceTask(InstrumentTask): #: Global variable to use for the sequence. sequence_vars = Typed(OrderedDict, ()).tag(pref=(ordered_dict_to_pref, ordered_dict_from_pref)) - + def check(self, *args, **kwargs): """Check that the sequence can be compiled. @@ -97,12 +97,11 @@ def perform(self): for k, v in infos.items(): self.write_in_database(k, v) - + def compile_and_plot(self, variables): """Compile the sequence and plot it. """ - seq = self.sequence context = seq.context for k, v in variables.items(): @@ -112,16 +111,15 @@ def compile_and_plot(self, variables): if not table: raise Exception('Failed to compile sequence :\n' + pformat(errors)) - freq = context.list_sequence_infos()['sampling_frequency'] - + freq = context.list_sequence_infos()['sampling_frequency'] + channel_num = len(table) - #fig, axs = plt.subplots(4,1, figsize=(15, 8)) - fig, axs = plt.subplots(channel_num,1, figsize=(15, 2.5*channel_num), + fig, axs = plt.subplots(channel_num, 1, figsize=(15, 2.5*channel_num), sharex=True) fig.subplots_adjust(hspace = 0.5, wspace=.001) - + x = np.arange(len(table[list(table.keys())[0]]))/freq*10**6 - + if len(list(table.keys())) == 1: key = list(table.keys())[0] axs.plot(x,table[key], label = 'wvfm')