def timed_update(): from pyface.timer.api import Timer def update_loop(line_plot): line_plot.update_data() # shouldn't need this # line_plot.autoscale_axis() def log_memory(): # log memory usage usage = float(psutil.Process(os.getpid()).memory_info().rss) * 1e-6 info = '#[{}] MB:{:f}'.format(-1, usage) logger.warning(info) plot = LinePlot() millisecs = int(1000.0 / 30.0) # ~30Hz update_timer = Timer(millisecs, update_loop, plot) log_timer = Timer(int(1000.0 * 10.0), log_memory) update_timer.Start() log_timer.Start() plot.configure_traits()
class MainWindow(ApplicationWindow): """ The main application window. """ # The pyface Timer. my_timer = Any() # Count each time the timer task executes. counter = Int def __init__(self, **traits): """ Creates a new application window. """ # Base class constructor. super(MainWindow, self).__init__(**traits) # Add a menu bar. self.menu_bar_manager = MenuBarManager( MenuManager( Action(name='Start Timer', on_perform=self._start_timer), Action(name='Stop Timer', on_perform=self._stop_timer), Action(name='E&xit', on_perform=self.close), name = '&File', ) ) return def _start_timer(self): """Called when the user selects "Start Timer" from the menu.""" if self.my_timer is None: # First call, so create a Timer. It starts automatically. self.my_timer = Timer(500, self._timer_task) else: self.my_timer.Start() def _stop_timer(self): """Called when the user selecte "Stop Timer" from the menu.""" if self.my_timer is not None: self.my_timer.Stop() def _timer_task(self): """The method run periodically by the timer.""" self.counter += 1 print "counter = %d" % self.counter
class Animator(HasTraits): """ Convenience class to manage a timer and present a convenient UI. This is based on the code in `tvtk.tools.visual`. Here is a simple example of using this class:: >>> from mayavi import mlab >>> def anim(): ... f = mlab.gcf() ... while 1: ... f.scene.camera.azimuth(10) ... f.scene.render() ... yield ... >>> anim = anim() >>> t = Animator(500, anim.next) >>> t.edit_traits() This makes it very easy to animate your visualizations and control it from a simple UI. **Notes** If you want to modify the data plotted by an `mlab` function call, please refer to the section on: :ref:`mlab-animating-data` """ ######################################## # Traits. start = Button('Start Animation') stop = Button('Stop Animation') delay = Range(10, 100000, 500, desc='frequency with which timer is called') # The internal timer we manage. timer = Instance(Timer) ###################################################################### # User interface view traits_view = View(Group(Item('start'), Item('stop'), show_labels=False), Item('_'), Item(name='delay'), title='Animation Controller', buttons=['OK']) ###################################################################### # Initialize object def __init__(self, millisec, callable, *args, **kwargs): """Constructor. **Parameters** :millisec: int specifying the delay in milliseconds between calls to the callable. :callable: callable function to call after the specified delay. :\*args: optional arguments to be passed to the callable. :\*\*kwargs: optional keyword arguments to be passed to the callable. """ HasTraits.__init__(self) self.delay = millisec self.timer = Timer(millisec, callable, *args, **kwargs) ###################################################################### # Non-public methods, Event handlers def _start_fired(self): self.timer.Start(self.delay) def _stop_fired(self): self.timer.Stop() def _delay_changed(self, value): t = self.timer if t is None: return if t.IsRunning(): t.Stop() t.Start(value)
class MainWindow(HasTraits): scene = Instance(MlabSceneModel, ()) view = View(Item('scene', editor=SceneEditor(), resizable=True, show_label=False), resizable=True, height=500.00, width=750.0) def __init__(self, config, server): HasTraits.__init__(self) self.mayavi_view = PlotHead(self, config, server) self.tail_data = np.zeros((2,3)) self.head_data = np.zeros((2,3)) self.reset = False self.init_plot() self.timer = Timer(2000, self.update_plot) self.timer.Start() def init_plot(self): # create a window with 14 plots (7 rows x 2 columns) ## create a window with 8 plots (4 rows x 2 columns) reader = tvtk.OBJReader() reader.file_name = self.mayavi_view.filename mapper = tvtk.PolyDataMapper() mapper.input = reader.output actor = tvtk.Actor() mapper.color_mode = 0x000000 actor.mapper = mapper actor.orientation = (180,0,90) self.scene.add_actor(actor) mlab.points3d(11.5, -1.3, -14) mlab.points3d(-6.6, -1.3, -13.5) mlab.points3d(3,-2,2) mlab.points3d(2, 9.5, -9.5) self.arrows = mlab.quiver3d(self.tail_data[:,0], self.tail_data[:,1], self.tail_data[:,2], self.head_data[:,0], self.head_data[:,1], self.head_data[:,2], scale_mode='vector', scale_factor=1.0) self.dots = mlab.points3d(self.tail_data[:,0], self.tail_data[:,1], self.tail_data[:,2], color=(1,1,0),opacity=0.5,scale_mode='vector', scale_factor=1.0) self.ar = self.arrows.mlab_source self.dot_source = self.dots.mlab_source ''' x_arrows = np.ones((300, 6)) y_arrows = np.ones((300, 6)) z_arrows = np.ones((300, 6)) arrows = np.ones((300, 6)) for i, pos in enumerate(arrows): x_arrows[i, 0] = pos[0] + i y_arrows[i, 1] = pos[1] + i z_arrows[i, 2] = pos[2] + i arrows = np.vstack((x_arrows, y_arrows, z_arrows, np.zeros((1,6)))) self.tail_data = np.vstack((self.tail_data, arrows[:,:3])) mlab.points3d(x_arrows[:,0], x_arrows[:,1], x_arrows[:,2], scale_factor = 0.5) mlab.quiver3d(x_arrows[:,0], x_arrows[:,1], x_arrows[:,2], x_arrows[:,3], x_arrows[:,4], x_arrows[:,5], scale_factor = 0.5) # z=arrows[:,2] self.head_data = np.vstack((self.head_data, arrows[:, -3:])) self.ar.reset(x=arrows[:,0] + self.mayavi_view.plot_vertex_vec[0], y=arrows[:,1] + self.mayavi_view.plot_vertex_vec[1], z=arrows[:,2] + self.mayavi_view.plot_vertex_vec[2], u=arrows[:,3]+10, v=arrows[:,4]+10,w=arrows[:,5]+10) ''' def update_plot(self): print 'started updating' if self.reset: while not queue.empty(): queue.get() self.head_data = np.zeros((2,3)) self.tail_data = np.zeros((2,3)) self.reset = False else: while not queue.empty(): new_values = queue.get() print new_values.shape self.tail_data = np.vstack((self.tail_data, new_values[1])) print 'updated position' self.head_data = np.vstack((self.head_data, new_values[0])) print 'updated rotation' print self.head_data print self.tail_data self.ar.reset(x=self.tail_data[:,0], y=self.tail_data[:,1], z=self.tail_data[:,2], u=self.head_data[:,0], v=self.head_data[:,1], w=self.head_data[:,2], scale_mode='vector', scale_factor=1.0) self.dot_source.reset(x=self.tail_data[:,0], y=self.tail_data[:,1], z=self.tail_data[:,2], color=(1,1,0),opacity=0.5,scale_mode='vector', scale_factor=1.0) print 'finished'
class Animator(HasTraits): start = Button('Start Animation') stop = Button('Stop Animation') next_frame = Button('+') prev_frame = Button('-') delay = Range(10, 100000, 500) loop = Bool(True) current_frame = Int(-1) _last_frame = Int() # TODO use Range(high="trait name") render_from_frame = Int() render_to_frame = Int() render_animation = Button() is_rendering = Bool(False) # indicator bool is True when rendering is_rendering_animation = Bool(False) render_directory = Directory("/tmp", exists=False) render_name_pattern = String("frame_%05d.png") magnification = Range(1, 128) fix_image_size = Bool(False) image_size = Tuple(Int(1280), Int(720)) render = Event() enable_cameraman = Bool(False) set_keyframe = Button() remove_keyframe = Button() timer = Instance(Timer) traits_view = View( Tabbed( Group( HGroup( Item('start', show_label=False), Item('stop', show_label=False), Item('next_frame', show_label=False, enabled_when='current_frame < _last_frame'), Item('prev_frame', show_label=False, enabled_when='current_frame > 0'), ), HGroup( Item(name = 'loop'), Item(name = 'delay'), ), Item(name = 'current_frame', editor=RangeEditor(is_float=False, high_name='_last_frame', mode='slider')), Group( HGroup( Item(name = 'enable_cameraman', label='enabled'), Item(name = 'set_keyframe', show_label=False), Item(name = 'remove_keyframe', show_label=False), Item(name = 'interpolation_type', object='object._camera_interpolator'), ), label = 'Cameraman', ), label = 'Timeline', ), Group( HGroup( Item('fix_image_size', label="Set Image Size"), Item('magnification', visible_when='not fix_image_size', label='Magnification'), Item('image_size', visible_when='fix_image_size', show_label=False, editor=TupleEditor(cols=2, labels=['W', 'H'])), ), Item("_"), Item("render_directory", label="Target Dir"), Item("render_name_pattern", label="Filename Pattern"), Item("_"), HGroup( Item("render_from_frame", label="from", editor=RangeEditor(is_float=False, low=0, high_name='render_to_frame')), Item("render_to_frame", label="to", editor=RangeEditor(is_float=False, low_name='render_from_frame', high_name='_last_frame')), ), Item("render_animation", show_label=False), label = "Render", ), ), title = 'Animation Controller', buttons = []) def __init__(self, num_frames, callable, millisec=40, figure=None, play=True, *args, **kwargs): HasTraits.__init__(self) self.delay = millisec self._last_frame = num_frames - 1 self._callable = callable if figure is None: figure = mlab.gcf() self._figure = figure self._camera_interpolator = tvtk.CameraInterpolator(interpolation_type='spline') self._t_keyframes = {} self.render_to_frame = self._last_frame self.timer = Timer(millisec, self._on_timer, *args, **kwargs) if not play: self.stop = True self._internal_generator = None self.current_frame = 0 self.on_trait_change(self._render, "render, current_frame", dispatch="ui") def _render(self): self.is_rendering = True if self._internal_generator is not None: try: next(self._internal_generator) except StopIteration: # is ok since generator should yield just once to render pass except: # catch and re-raise other errors raise else: raise "The render function should be either a simple function or a generator that yields just once to render" # before we call the user function, we want to disallow rendering # this speeds up animations that use mlab functions scene = self._figure.scene scene.disable_render = True r = self._callable(self.current_frame) if isinstance(r, types.GeneratorType): next(r) # save away generator to yield when another frame has to be displayed self._internal_generator = r # render scene without dumb hourglass cursor, # can be prevented by setting _interacting before calling render old_interacting = scene._interacting if self._camera_interpolator.number_of_cameras >= 2 and self.enable_cameraman: t = self.current_frame / float(self._last_frame) self._camera_interpolator.interpolate_camera(t, mlab.get_engine().current_scene.scene.camera) mlab.gcf().scene.renderer.reset_camera_clipping_range() scene._interacting = True scene.disable_render = False scene.render() scene._interacting = old_interacting self.is_rendering = False @on_trait_change('set_keyframe') def _set_keyframe(self): t = self.current_frame / float(self._last_frame) self._camera_interpolator.add_camera(t, mlab.get_engine().current_scene.scene.camera) self._t_keyframes[self.current_frame] = t def _next_frame_fired(self): self.current_frame += 1 def _prev_frame_fired(self): self.current_frame -= 1 @on_trait_change('remove_keyframe') def _remove_keyframe(self): if self.current_frame in self._t_keyframes: self._camera_interpolator.remove_last_keyframe(self._t_keyframes[self.current_frame]) def _on_timer(self, *args, **kwargs): if self.loop or self.current_frame != self._last_frame: self.current_frame = (self.current_frame + 1) % (self._last_frame + 1) else: self.stop = True def _delay_changed(self, value): t = self.timer if t is None: return if t.IsRunning(): t.Stop() t.Start(value) def _start_fired(self): if not self.loop and self.current_frame == self._last_frame: self.current_frame = 0 self.timer.Start(self.delay) def _stop_fired(self): self.timer.Stop() def _render_animation_fired(self): self.stop = True n_frames_render = self.render_to_frame - self.render_from_frame # prepare the render window renwin = self._figure.scene.render_window aa_frames = renwin.aa_frames renwin.aa_frames = 8 renwin.alpha_bit_planes = 1 # turn on off screen rendering #renwin.off_screen_rendering = True # set size of window if self.fix_image_size: orig_size = renwin.size renwin.size = self.image_size # render the frames progress = ProgressDialog(title="Rendering", max=n_frames_render, show_time=True, can_cancel=True) progress.open() self.is_rendering_animation = True for frame in range(self.render_from_frame, self.render_to_frame + 1): # move animation to desired frame, this will also render the scene self.current_frame = frame # prepare window to image writer render = tvtk.WindowToImageFilter(input=renwin, magnification=1)#, input_buffer_type='rgba') if not self.fix_image_size: render.magnification = self.magnification exporter = tvtk.PNGWriter(file_name=path.join(self.render_directory, self.render_name_pattern % frame)) configure_input(exporter,render) exporter.write() do_continue, skip = progress.update(frame - self.render_from_frame) if not do_continue: break # reset the render window to old values renwin.aa_frames = aa_frames if self.fix_image_size: renwin.size = orig_size #renwin.off_screen_rendering = False self.is_rendering_animation = False progress.close()
class TimeTrace(GetSetItemsMixin): number_of_points = Int(200, desc='Length of Count Trace', label='Number of points', mode='text', auto_set=False, enter_set=True) seconds_per_point = Float(0.1, desc='Seconds per point [s]', label='Seconds per point [s]', mode='text', auto_set=False, enter_set=True) # trace data count_rate = Array() time = Array() enable_0 = Bool(True, label='channel 0', desc='enable channel 0') enable_1 = Bool(False, label='channel 1', desc='enable channel 1') enable_2 = Bool(False, label='channel 2', desc='enable channel 2') enable_3 = Bool(False, label='channel 3', desc='enable channel 3') enable_4 = Bool(False, label='channel 4', desc='enable channel 4') enable_5 = Bool(False, label='channel 5', desc='enable channel 5') enable_6 = Bool(False, label='channel 6', desc='enable channel 6') enable_7 = Bool(False, label='channel 7', desc='enable channel 7') channels = Instance(list, factory=list) plot = Instance(Plot) plot_data = Instance(ArrayPlotData) start_button = Button(label='start', show_label=False) stop_button = Button(label='stop', show_label=False) clear_button = Button(label='clear', show_label=False) get_set_items = [ 'count_rate', 'time', 'channels', 'number_of_points', 'seconds_per_point' ] def __init__(self, tagger, **kwargs): super(TimeTrace, self).__init__(**kwargs) self.tagger = tagger self._reset() def _channels_default(self): return list( np.arange(8)[np.array([ self.enable_0, self.enable_1, self.enable_2, self.enable_3, self.enable_4, self.enable_5, self.enable_6, self.enable_7 ])]) @on_trait_change( 'enable_0,enable_1,enable_2,enable_3,enable_4,enable_5,enable_6,enable_7' ) def _update_channels(self): self.channels = self._channels_default() @on_trait_change('channels,number_of_points,seconds_per_point') def _reset(self): if hasattr(self, '_timer'): self._timer.Stop() self._create_plot() self._counter = Counter(self.tagger, self.channels, int(self.seconds_per_point * 1e12), self.number_of_points) self.time = self._counter.getIndex() * 1e-12 self.count_rate = self._counter.getData() / self.seconds_per_point self._timer = Timer(200, self._refresh_data) self._timer.Start() def _refresh_data(self): self.count_rate = self._counter.getData() / self.seconds_per_point def _count_rate_changed(self, new): for i, line_i in enumerate(new): self.plot_data.set_data('channel_' + str(self.channels[i]), line_i) def _time_changed(self, new): self.plot_data.set_data('time', new) def _create_plot(self): kwargs = {} for i, channel_i in enumerate(self.channels): kwargs['channel_' + str(channel_i)] = np.array(()) data = ArrayPlotData(time=np.array(()), **kwargs) plot = Plot(data, width=100, height=100, resizable='hv', padding_left=96, padding_bottom=32) plot.index_axis.title = 'time [s]' plot.value_axis.title = 'count rate [counts/s]' color_map = { 0: 'blue', 1: 'red', 2: 'green', 3: 'black', 4: 'brown', 5: 'yellow', 6: 'magenta', 7: 'cyan' } for channel in self.channels: plot.plot(('time', 'channel_' + str(channel)), type='line', color=color_map[channel], name='channel ' + str(channel)) plot.legend.align = 'll' if len(self.channels) > 1: plot.legend.visible = True else: plot.legend.visible = False self.plot_data = data self.plot = plot def _clear_button_fired(self): self._counter.clear() self.count_rate = self._counter.getData() def _start_button_fired(self): self._counter.start() self._timer.Start() def _stop_button_fired(self): self._counter.stop() self._timer.Stop() def __del__(self): self._timer.Stop() traits_view = View( VGroup( HGroup( Item('clear_button', show_label=False), Item('start_button', show_label=False), Item('stop_button', show_label=False), Item('save_button', show_label=False), ), HGroup( Item('plot', editor=ComponentEditor(size=(100, 100)), show_label=False), VGroup( Item('enable_0'), Item('enable_1'), Item('enable_2'), Item('enable_3'), Item('enable_4'), Item('enable_5'), Item('enable_6'), Item('enable_7'), ), ), HGroup( Item('number_of_points'), Item('seconds_per_point'), ), ), title='Counter', width=780, height=520, buttons=[], resizable=True, )
class DACChannel(traits.HasTraits): def __init__(self, setchannelName, port, connection, rpiADC): self.channelName = setchannelName self.x = ad.ADEvalBC() self.port = port self.connection = connection self.rpiADC = rpiADC self.wmLockTimer = Timer(1000, self.wmLock2) self.wmLockTimer.Stop() # time.sleep(5) # self.start_timer() update = traits.Button() set = traits.Button() pinMode = '0' relockMode = traits.Enum("Manual Mode", "Doubling cavity Relock", "Wavemeter Relock", "Wavemeter Lock") #set_Relock = traits.Button() #---- MANUAL MODE ----# voltage = traits.Float(desc="Voltage of the Channel") setVoltage = traits.Float(desc="set Voltage") powerModeMult = 0 channelName = traits.Str(desc="Name") channelDescription = traits.Str(desc="Description") powerMode = traits.Enum( 5, 10, 10.8, desc="power Mode", ) bipolar = traits.Bool(desc="Bipolarity") channelMessage = traits.Str() bytecode = traits.Str() port = traits.Str() def pinSet(self, channel, mode): cmd = "pin=" + channel + mode self.connection.send(cmd) #print cmd def _update_fired(self): if self.bipolar == True: a = "bipolar" bip = True self.powerModeMult = -1 else: a = "unipolar" bip = False self.powerModeMult = 0 cmd = "cmd=" + self.x.setMaxValue(self.port, self.powerMode, bip) #print cmd self.connection.send(cmd) b = "Mode set to %.1f" % self.powerMode self.channelMessage = b + ' ' + a self._set_fired() def _set_fired(self): if ((self.setVoltage > self.powerMode) and (self.bipolar == False)): print "setVoltage out of bounds. Not sending." elif ((abs(self.setVoltage) > self.powerMode) and (self.bipolar == True)): print "setVoltage out of bounds. Not sending." else: cmd = "cmd=" + self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, self.setVoltage) self.connection.send(cmd) self.bytecode = self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, self.setVoltage) self.voltage = self.setVoltage #---- MANUAL MODE GUI ----# voltageGroup = traitsui.HGroup(traitsui.VGroup( traitsui.Item('voltage', label="Measured Voltage", style_sheet='* { font-size: 18px; }', style="readonly"), traitsui.Item('setVoltage', label="Set Value"), ), traitsui.Item('set', show_label=False), show_border=True) powerGroup = traitsui.VGroup(traitsui.HGroup( traitsui.Item('powerMode', label="Power Mode"), traitsui.Item('bipolar'), ), traitsui.HGroup( traitsui.Item('update', show_label=False), traitsui.Item('channelMessage', show_label=False, style="readonly"), ), traitsui.Item('bytecode', show_label=False, style="readonly"), traitsui.Item('switch_Lock'), show_border=True) manualGroup = traitsui.VGroup(traitsui.Item('channelName', label="Channel Name", style="readonly"), voltageGroup, show_border=True, visible_when='relockMode == "Manual Mode"') #---- DOUBLING CAVITY MODE GUI----# adcChannel = traits.Enum(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, desc="Channel of the rpiADC") adcVoltage = traits.Float(desc="Voltage on rpiADC Channel") DCscan_and_lock = traits.Button() switch_Lock = traits.Button() DCconnect = traits.Bool() DCautolock = traits.Button() DCadcVoltages = None DCadcVoltagesMean = None DCtolerance = 0.01 #Volt DCmistakeCounter = 0 DCminBoundary = traits.Float() DCmaxBoundary = traits.Float() DCnoOfSteps = traits.Int() #Updates voltage of the selected channel" def _adcVoltage_update(self): self.adcVoltage = self._adcVoltage_get() #Gets voltage of the selected channel via rpiADC Client def _adcVoltage_get(self): return self.rpiADC.getResults()[self.adcChannel] # print "latest results = %s " % self.rpiADC.latestResults # self.rpiADC.getResults() # print "latest results = %s " % self.rpiADC.latestResults # if self.adcChannel in self.rpiADC.latestResults: # return self.rpiADC.latestResults[self.adcChannel] # else: # return -999 #As soon as the connect button is checked, automatic updating of the adc voltage is initiated. #When it is unchecked, the update stops def _DCconnect_changed(self): if self.DCconnect == True: self._start_PD_timer() else: self.PDtimer.stop() self.adcVoltage = -999 print "PD timer stopped." #Starts the timer, that only updates the displayed voltage def _start_PD_timer(self): self.PDtimer = Timer(1000.0, self._adcVoltage_update) #Starts a timer, that updates the displayed voltage, as well as does the "in lock" checking def _start_PD_lock_timer(self): self.PDtimer = Timer(1000.0, self.update_PD_and_Lock) #Controls if everything is still in lock. Also updates displayed voltage. It counts still in lock, when the measured frequency #is within DC tolerance of the mean of the last five measured frequencies. def update_PD_and_Lock(self): self._adcVoltage_update() #still display Voltage pdVoltage = self._adcVoltage_get() #print "Updated Frequency" #mistakeCounter = 0 if len(self.DCadcVoltages ) < 5: #number of Measurements that will be compared print "Getting Data for Lock. Do not unlock!" self.DCadcVoltages = np.append(self.DCadcVoltages, pdVoltage) else: self.DCadcVoltagesMean = np.mean( self.DCadcVoltages) #Mean Frequency to compare to if (abs(pdVoltage - self.DCadcVoltagesMean) < self.DCtolerance): self.DCadcVoltages = np.append(self.DCadcVoltages, pdVoltage) self.DCadcVoltages = np.delete( self.DCadcVoltages, 0) #keep Array at constant length print "Still locked." if self.DCmistakeCounter > 0: self.DCmistakeCounter = 0 else: self.DCmistakeCounter += 1 if self.DCmistakeCounter > 5: self.PDtimer.stop() self._start_PD_timer() #keep Frequency on display.. self._DCscan_and_lock_fired() self._DCautolock_fired() else: print self.DCmistakeCounter #This button is used, when everything is already locked. It prepares the voltage mean array, stops the PD timer and starts the update_PD_and_Lock timer routine def _DCautolock_fired(self): if self.DCconnect == True: self.DCadcVoltages = np.array([]) self.PDtimer.stop() self._start_PD_lock_timer() else: print "No adcRPi connected." #This function (button) scans the voltage and reads the RPiADC voltage of the selected channel. It subsequently attempts #to lock the Cavity at the voltage, where the RPiADC voltage is highest. The Algorithm for the lock is as follows: #1) It does a coarse DAC voltage scan with the parameters selected in the input (minBoundary etc). This scan is terminated when # the adc voltage goes above a threshold (3.2 V - hardcoded, maybe add input), or after scanning the whole range. #2) A fine scan 0.3V(dac) around the maximum (or around the 3.2V dac voltage) is done. Currently the number of steps is hardcoded to 600, # which worked well. This scan terminated either by going to a 3.3V (adc) threshhold or after finishing. #3) The Cavity is locked at a dac voltage that corresponds to either the maximum after the whole scan or the 3.3V threshold. def _DCscan_and_lock_fired(self): self.pinSet(self.port, '1') #Unlock time.sleep( 1 ) #If the cavity was in lock before we can not directly start scanning, or else it will read 3.3V as first value voltages = np.linspace( self.DCminBoundary, self.DCmaxBoundary, self.DCnoOfSteps) #Parameters for first scan set by GUI diodeVoltages = np.array([]) for entry in voltages: #First scan self.setVoltage = entry self._set_fired() #update setVoltage diodeVoltages = np.append(diodeVoltages, self._adcVoltage_get()) volt = self._adcVoltage_get() print volt if volt >= 3.2: #Threshold for first scan break time.sleep( 0.05 ) #sleep time between every step for adc readout, maybe it is possible to make the scan faster self.setVoltage = voltages[diodeVoltages.argmax( axis=0)] #DAC Voltage corresponding to the highest adc voltage print "Attempting to reduce scan Range" print self.setVoltage time.sleep(2.0) if self.setVoltage < 0.3: #make sure we do not scan below zero, as the lock box does not like negative voltages. auxSetVolt = 0 else: auxSetVolt = self.setVoltage - 0.3 voltages = np.linspace(auxSetVolt, self.setVoltage + 0.3, 600) #parameters for second scan diodeVoltages = np.array([]) for entry in voltages: #Second scan if entry > self.powerMode: #Our voltage can not go above our maximum value break self.setVoltage = entry self._set_fired() diodeVoltages = np.append(diodeVoltages, self._adcVoltage_get()) volt = self._adcVoltage_get() print volt if volt >= 3.3: #threshold for second scan print self.setVoltage self.pinSet(self.port, '0') return time.sleep(0.1) self.setVoltage = voltages[diodeVoltages.argmax(axis=0)] print "DAC Voltage set to %f" % voltages[diodeVoltages.argmax(axis=0)] print ".. this corresponds to a diode Voltage of %f" % diodeVoltages[ diodeVoltages.argmax(axis=0)] self._set_fired() time.sleep(0.2) self.pinSet(self.port, '0') #Lock print "Voltage set to %f to attempt relock." % self.setVoltage return #Changes from lock to dither and other way around def _switch_Lock_fired(self): if self.pinMode == '0': self.pinMode = '1' self.pinSet(self.port, self.pinMode) else: self.pinMode = '0' self.pinSet(self.port, self.pinMode) #Gui Stuff# DCgroup = traitsui.VGroup( traitsui.HGroup( traitsui.VGroup( traitsui.Item('adcChannel'), traitsui.Item('adcVoltage', style='readonly'), ), traitsui.VGroup( traitsui.Item('DCmaxBoundary'), traitsui.Item('DCminBoundary'), traitsui.Item('DCnoOfSteps'), ), ), #traitsui.Item('switch_Lock'), traitsui.HGroup( traitsui.VGroup( traitsui.Item('DCscan_and_lock'), traitsui.Item('DCautolock'), ), traitsui.Item('DCconnect')), visible_when='relockMode == "Doubling cavity Relock"', show_border=True, ) #---- WAVEMETER GUI ----# wavemeter = traits.Enum("Humphry", "Ion Cavity") wmChannel = traits.Enum(1, 2, 3, 4, 5, 6, 7, 8) wmFrequency = traits.Float() wmConnected = traits.Bool() wmHWI = None wmIP = None wmPort = None wmReLock = traits.Button() wmFrequencyLog = np.array([]) wmMeanFrequency = None wmTolerance = 0.0000006 #Frequency tolerance in THz, set to 60 MHz in accordance with wm accuracy mistakeCounter = 0 #wmPolarity = traits.Enum("+", "-") wmEmptyMemory = traits.Button() #When hitting wmConnected, a connection to the wavemeter and readout is established def _wmConnected_changed(self): if self.wmConnected == True: if self.wavemeter == "Humphry": self.wmIP = '192.168.0.111' self.wmPort = 6101 elif self.wavemeter == "Ion Cavity": self.wmIP = '192.168.32.2' self.wmPort = 6100 self.wmHWI = PyHWI.DECADSClientConnection('WLM', self.wmIP, self.wmPort) #frequencyArray = wmHWI.getFrequency(True, self.wmChannel) self.start_timer() else: self.wmFrequency = -999 self.timer.Stop() #stops either lock_timer or read_timer. print "Timer stopped" #GUI stuff wmGroup = traitsui.VGroup(traitsui.Item('wmFrequency', style='readonly'), traitsui.Item('wmConnected'), traitsui.Item('wmReLock'), traitsui.HGroup( traitsui.Item('wavemeter'), traitsui.Item('wmChannel'), traitsui.Item('wmEmptyMemory', show_label=False)), visible_when='relockMode == "Wavemeter Relock"') #Resets the memory of the lock (the array which saves the last read frequencies) def _wmEmptyMemory_fired(self): self.wmFrequencyLog = np.array([]) print "Memory empty." #starts readout-only timer def start_timer(self): print "Timer started" self.timer = Timer(1000.0, self.update_wm) #starts readout-and-lock timer, analogue to the doubling cavity case def start_lock_timer(self): print "Lock timer started" self.timer = Timer(1000.0, self.update_wm_and_lock) #updates the displayed frequency def update_wm(self): frequencyArray = self.wmHWI.getFrequency(True, self.wmChannel) self.wmFrequency = frequencyArray[1] #updates frequency and checks if its still near the mean of the last five (hardcoded, see below) measured frequencies. If not, it attempts a relock. def update_wm_and_lock(self): self.update_wm() frequencyArray = self.wmHWI.getFrequency(True, self.wmChannel) #print "Updated Frequency" #mistakeCounter = 0 if len(self.wmFrequencyLog ) < 5: #number of Measurements that will be compared print "Getting Data for Lock. Do not unlock!" self.wmFrequencyLog = np.append(self.wmFrequencyLog, frequencyArray[1]) else: self.wmMeanFrequency = np.mean( self.wmFrequencyLog) #Mean Frequency to compare to if (abs(frequencyArray[1] - self.wmMeanFrequency) < self.wmTolerance): self.wmFrequencyLog = np.append(self.wmFrequencyLog, frequencyArray[1]) self.wmFrequencyLog = np.delete( self.wmFrequencyLog, 0) #keep Array at constant length print "Still locked." if self.mistakeCounter > 0: self.mistakeCounter = 0 else: self.mistakeCounter += 1 if self.mistakeCounter > 5: #number of measurements that still count as locked, though the frequency is not within boundaries self.timer.stop() self.start_timer() #keep Frequency on display.. self.wmRelock(self.wmMeanFrequency) else: print self.mistakeCounter #Relock procedure. #For now this scans only one time, with a hardcoded number of steps. It might be worth modifying this to look like the doubling cavity relock procedure. def wmRelock(self, wantedFrequency): self.pinSet(self.port, '1') voltages = np.linspace(self.powerModeMult * self.powerMode, self.powerMode, 10) wmRelockTry = 0 try: while (wmRelockTry < 5): #attempt relock five times for entry in voltages: self.setVoltage = entry self._set_fired() time.sleep(1.0) frequencyArray = self.wmHWI.getFrequency( True, self.wmChannel) if (abs(frequencyArray[1] - wantedFrequency) < self.wmTolerance): print "Relock_attempt!" self.pinSet(self.port, '0') self._wmLock_fired() raise GetOutOfLoop #Opens the function again (inductively). Maybe fix that by going back #to the level above somehow. wmRelockTry += 1 print "Relock try %f not succesful" % wmRelockTry print "Was not able to Relock." except GetOutOfLoop: print "gotOutOfLoop" pass def _wmReLock_fired(self): #self.wmFrequencyLog = np.array([]) self.mistakeCounter = 0 if self.wmConnected == True: self.timer.Stop( ) #Switch from read-only timer to read-and-log timer. If both run at the same time self.start_lock_timer() #we run into timing problems. else: print "No Wavemeter connected!" print "hi" #---- WAVEMETERLOCK - DE 17092018 GUI ----# wavemeter = traits.Enum("Humphry", "Ion Cavity") wmChannel = traits.Enum(1, 2, 3, 4, 5, 6, 7, 8) wmFrequency = traits.Float() wmConnected = traits.Bool() wmHWI = None wmIP = None wmPort = None isRunning = traits.Bool(False) wmVoltage = 0 wmLockTimer = traits.Instance(Timer) wmLockStart = traits.Button() wmLockStop = traits.Button() wmFrequencyLog = np.array([]) wmMeanFrequency = None wmTargetFrequency = traits.Float() #frequency to lock wmGain = traits.Float() #Gain for wavemeterlock wmTolerance = 0.0000006 #Frequency tolerance in THz, set to 60 MHz in accordance with wm accuracy mistakeCounter = 0 #wmPolarity = traits.Enum("+", "-") wmEmptyMemory = traits.Button() #GUI stuff wmlockGroup = traitsui.VGroup( traitsui.HGroup(traitsui.Item('wavemeter'), traitsui.Item('wmChannel'), traitsui.Item('wmEmptyMemory', show_label=False)), traitsui.Item('wmFrequency', style='readonly'), traitsui.Item('wmConnected'), traitsui.Item('wmTargetFrequency'), traitsui.Item('wmGain'), traitsui.HGroup( traitsui.Item('wmLockStart', visible_when="isRunning == False"), traitsui.Item('wmLockStop', visible_when="isRunning == True")), visible_when='relockMode == "Wavemeter Lock"') def _wmLockStart_fired(self): print "Start: Wavemeterlock" self.isRunning = True self.wmLockTimer.Start() def wmLock2(self): # Calculate error in MHz error = (self.wmFrequency - self.wmTargetFrequency) * 10**3 if abs(error) < 5000: self.wmVoltage = self.wmVoltage + error * self.wmGain if self.wmVoltage > 10: self.wmVoltage = 10 elif self.wmVoltage < -10: self.wmVoltage = -10 cmd = "cmd=" + self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, self.wmVoltage) self.connection.sendwithoutcomment(cmd) self.bytecode = self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, self.wmVoltage) #self.saveToFile( "frequency_data.csv" ) def _wmLockStop_fired(self): print "Stop: Wavemeterlock" self.isRunning = False cmd = "cmd=" + self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, 0) #Spannung wieder auf 0 self.connection.sendwithoutcomment(cmd) self.bytecode = self.x.generate_voltage( self.port, self.powerMode, self.powerModeMult * self.powerMode, 0) self.wmVoltage = 0 self.wmLockTimer.Stop() def saveToFile(self, fileName): f = open(fileName, "a") f.write("%f \n" % self.wmFrequency) f.close() #---- PUT TOGETHER CHANNEL ----# selectionGroup = traitsui.HGroup(traitsui.Item('relockMode'), #traitsui.Item('set_Relock'), ) channelGroup = traitsui.VGroup( selectionGroup, powerGroup, wmGroup, wmlockGroup, DCgroup, manualGroup, ) traits_view = traitsui.View(channelGroup)