def load_poke(self, poke_filename=None): sensor_mutex.lock() mirror_mutex.lock() try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.' % poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", ccfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py, px = poke.shape expected_py = self.sensor.n_lenslets * 2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py, expected_px)) try: assert (py == expected_py and px == expected_px) except AssertionError as ae: error_message( 'Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.' % (py, px, expected_py, expected_px)) poke = dummy self.poke = Poke(poke) sensor_mutex.unlock() mirror_mutex.unlock()
def run_poke(self): cmin = ccfg.poke_command_min cmax = ccfg.poke_command_max n_commands = ccfg.poke_n_command_steps commands = np.linspace(cmin, cmax, n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets, n_actuators, n_commands)) y_mat = np.zeros((n_lenslets, n_actuators, n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] print k_actuator, cur self.mirror.set_actuator(k_actuator, cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() sensor_mutex.lock() x_mat[:, k_actuator, k_command] = self.sensor.x_slopes y_mat[:, k_actuator, k_command] = self.sensor.y_slopes sensor_mutex.unlock() self.finished.emit() # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat, axis=2) d_y_mat = np.diff(y_mat, axis=2) x_response = np.mean(d_x_mat / d_commands, axis=2) y_response = np.mean(d_y_mat / d_commands, axis=2) poke = np.vstack((x_response, y_response)) ns = now_string() poke_fn = os.path.join(ccfg.poke_directory, '%s_poke.txt' % ns) command_fn = os.path.join(ccfg.poke_directory, '%s_currents.txt' % ns) chart_fn = os.path.join(ccfg.poke_directory, '%s_modes.pdf' % ns) np.savetxt(poke_fn, poke) np.savetxt(command_fn, commands) save_modes_chart(chart_fn, poke, commands, self.mirror.mask) self.poke = Poke(poke) time.sleep(1) self.unpause()
def load_poke(self,poke_filename=None): sensor_mutex.lock() mirror_mutex.lock() try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.'%poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", kcfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py,px = poke.shape expected_py = self.sensor.n_lenslets*2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py,expected_px)) try: assert (py==expected_py and px==expected_px) except AssertionError as ae: error_message('Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.'%(py,px,expected_py,expected_px)) poke = dummy self.poke = Poke(poke) sensor_mutex.unlock() mirror_mutex.unlock()
def run_poke(self): cmin = kcfg.poke_command_min cmax = kcfg.poke_command_max n_commands = kcfg.poke_n_command_steps commands = np.linspace(cmin,cmax,n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets,n_actuators,n_commands)) y_mat = np.zeros((n_lenslets,n_actuators,n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] print k_actuator,cur self.mirror.set_actuator(k_actuator,cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() sensor_mutex.lock() x_mat[:,k_actuator,k_command] = self.sensor.x_slopes y_mat[:,k_actuator,k_command] = self.sensor.y_slopes sensor_mutex.unlock() self.finished.emit() # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat,axis=2) d_y_mat = np.diff(y_mat,axis=2) x_response = np.mean(d_x_mat/d_commands,axis=2) y_response = np.mean(d_y_mat/d_commands,axis=2) poke = np.vstack((x_response,y_response)) ns = now_string() poke_fn = os.path.join(kcfg.poke_directory,'%s_poke.txt'%ns) command_fn = os.path.join(kcfg.poke_directory,'%s_currents.txt'%ns) chart_fn = os.path.join(kcfg.poke_directory,'%s_modes.pdf'%ns) np.savetxt(poke_fn,poke) np.savetxt(command_fn,commands) save_modes_chart(chart_fn,poke,commands,self.mirror.mirror_mask) self.poke = Poke(poke) time.sleep(1) self.unpause()
class Loop(QObject): finished = pyqtSignal() pause_signal = pyqtSignal() unpause_signal = pyqtSignal() def __init__(self, sensor, mirror): super(Loop, self).__init__() self.mirror_thread = QThread() self.sensor_thread = QThread() self.sensor = sensor self.active_lenslets = np.ones(self.sensor.n_lenslets).astype(int) self.mirror = mirror n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators dummy = np.ones((2 * n_lenslets, n_actuators)) outfn = os.path.join(ccfg.poke_directory, 'dummy_poke.txt') np.savetxt(outfn, dummy) #DEBUG self.sensor.moveToThread(self.sensor_thread) self.mirror.moveToThread(self.mirror_thread) # We have to connect the mirror timer's timeout signal # to the mirror update slot, and then start the timer # here. It's a little awkward, but the mirror timer # cannot be started until it's in its own thread, and # because we've used moveToThread (instead of # making Mirror a QThread subclass). self.mirror.timer.timeout.connect(self.mirror.update) self.mirror.timer.start(1.0 / self.mirror.update_rate * 1000.0) self.sensor_thread.started.connect(self.sensor.update) self.finished.connect(self.sensor.update) self.sensor.finished.connect(self.update) self.pause_signal.connect(self.sensor.pause) self.pause_signal.connect(self.mirror.pause) self.unpause_signal.connect(self.sensor.unpause) self.unpause_signal.connect(self.mirror.unpause) self.poke = None self.closed = False try: self.load_poke(ccfg.poke_filename) except Exception as e: self.load_poke() self.gain = ccfg.loop_gain self.loss = ccfg.loop_loss self.paused = False def has_poke(self): return self.poke is not None def start(self): self.sensor_thread.start() self.mirror_thread.start() def pause(self): self.pause_signal.emit() self.paused = True def unpause(self): self.unpause_signal.emit() self.paused = False self.finished.emit() print 'loop unpaused' @pyqtSlot() def update(self): if not self.paused: sensor_mutex.lock() mirror_mutex.lock() # compute the mirror command here if self.closed and self.has_poke(): current_active_lenslets = np.zeros(self.active_lenslets.shape) current_active_lenslets[np.where( self.sensor.box_maxes > ccfg.spots_threshold)] = 1 if not all(self.active_lenslets == current_active_lenslets): self.active_lenslets[:] = current_active_lenslets[:] self.poke.invert(mask=self.active_lenslets) xs = self.sensor.x_slopes[np.where(self.active_lenslets)[0]] ys = self.sensor.y_slopes[np.where(self.active_lenslets)[0]] slope_vec = np.hstack((xs, ys)) command = self.gain * np.dot(self.poke.ctrl, slope_vec) command = self.mirror.get_command() * (1 - self.loss) - command self.mirror.set_command(command) self.finished.emit() sensor_mutex.unlock() mirror_mutex.unlock() def load_poke(self, poke_filename=None): sensor_mutex.lock() mirror_mutex.lock() try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.' % poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", ccfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py, px = poke.shape expected_py = self.sensor.n_lenslets * 2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py, expected_px)) try: assert (py == expected_py and px == expected_px) except AssertionError as ae: error_message( 'Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.' % (py, px, expected_py, expected_px)) poke = dummy self.poke = Poke(poke) sensor_mutex.unlock() mirror_mutex.unlock() def invert(self): if self.poke is not None: self.pause() time.sleep(1) self.poke.invert() time.sleep(1) QApplication.processEvents() self.unpause() time.sleep(1) def set_n_modes(self, n): try: self.poke.n_modes = n except Exception as e: print e def get_n_modes(self): out = -1 try: out = self.poke.n_modes except Exception as e: print e return out def get_condition_number(self): out = -1 try: out = self.poke.cutoff_cond except Exception as e: print e return out def run_poke(self): cmin = ccfg.poke_command_min cmax = ccfg.poke_command_max n_commands = ccfg.poke_n_command_steps commands = np.linspace(cmin, cmax, n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets, n_actuators, n_commands)) y_mat = np.zeros((n_lenslets, n_actuators, n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] print k_actuator, cur self.mirror.set_actuator(k_actuator, cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() sensor_mutex.lock() x_mat[:, k_actuator, k_command] = self.sensor.x_slopes y_mat[:, k_actuator, k_command] = self.sensor.y_slopes sensor_mutex.unlock() self.finished.emit() # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat, axis=2) d_y_mat = np.diff(y_mat, axis=2) x_response = np.mean(d_x_mat / d_commands, axis=2) y_response = np.mean(d_y_mat / d_commands, axis=2) poke = np.vstack((x_response, y_response)) ns = now_string() poke_fn = os.path.join(ccfg.poke_directory, '%s_poke.txt' % ns) command_fn = os.path.join(ccfg.poke_directory, '%s_currents.txt' % ns) chart_fn = os.path.join(ccfg.poke_directory, '%s_modes.pdf' % ns) np.savetxt(poke_fn, poke) np.savetxt(command_fn, commands) save_modes_chart(chart_fn, poke, commands, self.mirror.mask) self.poke = Poke(poke) time.sleep(1) self.unpause() def set_closed(self, val): self.closed = val
def run_poke(self): cmin = ccfg.poke_command_min cmax = ccfg.poke_command_max n_commands = ccfg.poke_n_command_steps commands = np.linspace(cmin, cmax, n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets, n_actuators, n_commands)) y_mat = np.zeros((n_lenslets, n_actuators, n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] #print k_actuator,cur self.mirror.set_actuator(k_actuator, cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() self.sensor_mutex.lock() x_mat[:, k_actuator, k_command] = self.sensor.x_slopes y_mat[:, k_actuator, k_command] = self.sensor.y_slopes # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat, axis=2) d_y_mat = np.diff(y_mat, axis=2) x_response = np.mean(d_x_mat / d_commands, axis=2) y_response = np.mean(d_y_mat / d_commands, axis=2) poke = np.vstack((x_response, y_response)) ns = now_string() # After we make a new poke matrix, we will save it in # two files: an archive file that can be used to keep # track of old poke matrices, and the file specified # in the config file, e.g., 'poke.txt'. # The archive filename will use the time date string # generated above. This filename will also be used to # save the commands and the mirror mode chart PDF. poke_fn = ccfg.poke_filename archive_poke_fn = os.path.join(ccfg.poke_directory, '%s_poke.txt' % ns) archive_command_fn = os.path.join(ccfg.poke_directory, '%s_currents.txt' % ns) archive_chart_fn = os.path.join(ccfg.poke_directory, '%s_modes.pdf' % ns) np.savetxt(poke_fn, poke) np.savetxt(archive_poke_fn, poke) np.savetxt(archive_command_fn, commands) save_modes_chart(archive_chart_fn, poke, commands, self.mirror.mirror_mask) self.poke = Poke(poke) time.sleep(1) self.unpause()
class SerialLoop(QObject): def __init__(self, sensor, mirror, verbose=0): super(SerialLoop, self).__init__() self.verbose = verbose self.sensor = sensor self.active_lenslets = np.ones(self.sensor.n_lenslets).astype(int) self.mirror = mirror n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators self.poke = None self.closed = False # try to load the poke file specified in # ciao_config.py; if it doesn't exist, create # a dummy poke with all 1's; this will result # in an inverse control matrix with very low # gains, i.e. the mirror won't be driven if not os.path.exists(ccfg.poke_filename): dummy = np.ones((2 * n_lenslets, n_actuators)) np.savetxt(ccfg.poke_filename, dummy) self.load_poke(ccfg.poke_filename) self.gain = ccfg.loop_gain self.loss = ccfg.loop_loss self.paused = False self.n = 0 def has_poke(self): return self.poke is not None def pause(self): self.paused = True def unpause(self): self.paused = False def start(self): if self.verbose >= 5: print 'Starting loop.' def update(self): if not self.paused: if self.verbose >= 5: print 'Updating loop.' if self.closed and self.has_poke(): current_active_lenslets = np.zeros(self.active_lenslets.shape) current_active_lenslets[np.where( self.sensor.box_maxes > ccfg.spots_threshold)] = 1 n_active_lenslets = int(np.sum(current_active_lenslets)) if ccfg.poke_invert_on_demand: if not all( self.active_lenslets == current_active_lenslets): self.active_lenslets[:] = current_active_lenslets[:] self.poke.invert(mask=self.active_lenslets) else: if not self.sensor.n_lenslets == n_active_lenslets: return xs = self.sensor.x_slopes[np.where(self.active_lenslets)[0]] ys = self.sensor.y_slopes[np.where(self.active_lenslets)[0]] if self.verbose >= 1: error = self.sensor.error pcount = int(round(error * 1e8)) print 'rms' + '.' * pcount slope_vec = np.hstack((xs, ys)) command = self.gain * np.dot(self.poke.ctrl, slope_vec) command = self.mirror.get_command() * (1 - self.loss) - command self.mirror.set_command(command) if self.verbose >= 1: if command.max() > ccfg.mirror_command_max * .95: print 'actuator saturated' if command.min() < ccfg.mirror_command_min * .95: print 'actuator saturated' self.n = self.n + 1 def load_poke(self, poke_filename=None): try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.' % poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", ccfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py, px = poke.shape expected_py = self.sensor.n_lenslets * 2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py, expected_px)) try: assert (py == expected_py and px == expected_px) except AssertionError as ae: error_message( 'Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.' % (py, px, expected_py, expected_px)) poke = dummy self.poke = Poke(poke) def invert(self): if self.poke is not None: self.pause() time.sleep(1) self.poke.invert() time.sleep(1) QApplication.processEvents() self.unpause() time.sleep(1) def set_n_modes(self, n): try: self.poke.n_modes = n except Exception as e: print e def get_n_modes(self): out = -1 try: out = self.poke.n_modes except Exception as e: print e return out def get_condition_number(self): out = -1 try: out = self.poke.cutoff_cond except Exception as e: print e return out def run_poke(self): cmin = ccfg.poke_command_min cmax = ccfg.poke_command_max n_commands = ccfg.poke_n_command_steps commands = np.linspace(cmin, cmax, n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets, n_actuators, n_commands)) y_mat = np.zeros((n_lenslets, n_actuators, n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] #print k_actuator,cur self.mirror.set_actuator(k_actuator, cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() self.sensor_mutex.lock() x_mat[:, k_actuator, k_command] = self.sensor.x_slopes y_mat[:, k_actuator, k_command] = self.sensor.y_slopes # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat, axis=2) d_y_mat = np.diff(y_mat, axis=2) x_response = np.mean(d_x_mat / d_commands, axis=2) y_response = np.mean(d_y_mat / d_commands, axis=2) poke = np.vstack((x_response, y_response)) ns = now_string() # After we make a new poke matrix, we will save it in # two files: an archive file that can be used to keep # track of old poke matrices, and the file specified # in the config file, e.g., 'poke.txt'. # The archive filename will use the time date string # generated above. This filename will also be used to # save the commands and the mirror mode chart PDF. poke_fn = ccfg.poke_filename archive_poke_fn = os.path.join(ccfg.poke_directory, '%s_poke.txt' % ns) archive_command_fn = os.path.join(ccfg.poke_directory, '%s_currents.txt' % ns) archive_chart_fn = os.path.join(ccfg.poke_directory, '%s_modes.pdf' % ns) np.savetxt(poke_fn, poke) np.savetxt(archive_poke_fn, poke) np.savetxt(archive_command_fn, commands) save_modes_chart(archive_chart_fn, poke, commands, self.mirror.mirror_mask) self.poke = Poke(poke) time.sleep(1) self.unpause() def set_closed(self, val): self.closed = val
import pygame from tkinter import * import subprocess from poke import Poke import random import time from PIL import ImageTk, Image root = Tk() canvas = Canvas(root, bg="blue", height=430, width=730) canvas.pack() player = Poke('fire') enemy = Poke('water') pygame.mixer.init() pygame.mixer.music.load("Battle_music.wav") pygame.mixer.music.play() def enemy_move(): move = random.randint(1, 4) if move == 1: enemy.pound(player) subprocess.call(["afplay", "oof.wav"]) if player.health <= 0: subprocess.call(["afplay", "win_battle.wav"]) print("Player has been defeated!") quit()
class Loop(QObject): finished = pyqtSignal() started = pyqtSignal() def __init__(self,sensor,mirror,verbose=0): super(Loop,self).__init__() self.verbose = verbose self.sensor = sensor self.active_lenslets = np.ones(self.sensor.n_lenslets).astype(int) self.mirror = mirror self.update_rate = ccfg.loop_update_rate n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators self.poke = None self.closed = False self.safe = True # try to load the poke file specified in # ciao_config.py; if it doesn't exist, create # a dummy poke with all 1's; this will result # in an inverse control matrix with very low # gains, i.e. the mirror won't be driven if not os.path.exists(ccfg.poke_filename): dummy = np.ones((2*n_lenslets,n_actuators)) np.savetxt(ccfg.poke_filename,dummy) self.load_poke(ccfg.poke_filename) self.gain = ccfg.loop_gain self.loss = ccfg.loop_loss self.paused = False self.n = 0 self.started.connect(self.sensor.beeper.cache_tones) def start(self): self.timer = QTimer() self.timer.timeout.connect(self.update) self.timer.start(1.0/self.update_rate*1000.0) self.started.emit() def has_poke(self): return self.poke is not None def pause(self): self.mirror.pause() self.sensor.pause() self.paused = True def unpause(self): self.mirror.unpause() self.sensor.unpause() self.paused = False print 'loop unpaused' def set_safe(self,val): self.safe = val def set_paused(self,val): if val: self.mirror.pause() self.sensor.pause() self.paused = True else: self.mirror.unpause() self.sensor.unpause() self.paused = False @pyqtSlot() def update(self): if not self.paused: if self.verbose>=5: print 'Updating loop.' self.sensor.update() current_active_lenslets = np.ones(self.active_lenslets.shape) # if we're in safe mode, check the boxes: if self.safe: current_active_lenslets[np.where(self.sensor.box_maxes<ccfg.spots_threshold)] = 0 if self.closed and self.has_poke(): lenslets_changed = not all(self.active_lenslets==current_active_lenslets) all_lenslets_active = np.sum(current_active_lenslets)==self.sensor.n_lenslets # if the lenslets have changed, we have two options: # 1. if they're not all active, and ccfg.poke_invert_on_demand # is set to True, then we do one of two things: # a. if the active lenslets have changed, then we need to # re-invert and set ready_to_correct True # b. if the active lenslets haven't changed, then we just # set ready_to_correct true # 2. if they're not all active, and ccfg.poke_invert_on_demand # is set to False, then we need to set ready_to_correct to False # 3. if they're all active, set ready_to_correct True if not all_lenslets_active: if ccfg.poke_invert_on_demand: if lenslets_changed: self.poke.invert(mask=current_active_lenslets) self.ready_to_correct = True else: self.ready_to_correct = False else: self.ready_to_correct = True xs = self.sensor.x_slopes[np.where(current_active_lenslets)[0]] ys = self.sensor.y_slopes[np.where(current_active_lenslets)[0]] if self.ready_to_correct: assert 2*len(xs)==self.poke.ctrl.shape[1] if self.verbose>=1: error = self.sensor.error pcount = int(round(error*1e8)) print 'rms'+'.'*pcount if self.ready_to_correct: slope_vec = np.hstack((xs,ys)) command = self.gain * np.dot(self.poke.ctrl,slope_vec) command = self.mirror.get_command()*(1-self.loss) - command self.mirror.set_command(command) self.mirror.update() if self.verbose>=1: if command.max()>ccfg.mirror_command_max*.99: print 'actuator saturated' if command.min()<ccfg.mirror_command_min*.99: print 'actuator saturated' else: print 'not ready to correct' self.active_lenslets[:] = current_active_lenslets[:] self.n = self.n + 1 self.finished.emit() def load_poke(self,poke_filename=None): try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.'%poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", ccfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py,px = poke.shape expected_py = self.sensor.n_lenslets*2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py,expected_px)) try: assert (py==expected_py and px==expected_px) except AssertionError as ae: error_message('Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.'%(py,px,expected_py,expected_px)) poke = dummy self.poke = Poke(poke) self.close_ok = ccfg.loop_condition_llim<self.get_condition_number()<ccfg.loop_condition_ulim def invert(self): if self.poke is not None: self.pause() time.sleep(1) self.poke.invert() time.sleep(1) QApplication.processEvents() self.unpause() time.sleep(.001) self.close_ok = ccfg.loop_condition_llim<self.get_condition_number()<ccfg.loop_condition_ulim def set_n_modes(self,n): try: self.poke.n_modes = n except Exception as e: print e def get_n_modes(self): out = -1 try: out = self.poke.n_modes except Exception as e: print e return out def get_condition_number(self): out = -1 try: out = self.poke.cutoff_cond except Exception as e: print e if out>2**32: out = np.inf return out def run_poke(self): cmin = ccfg.poke_command_min cmax = ccfg.poke_command_max n_commands = ccfg.poke_n_command_steps commands = np.linspace(cmin,cmax,n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets,n_actuators,n_commands)) y_mat = np.zeros((n_lenslets,n_actuators,n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] #print k_actuator,cur self.mirror.set_actuator(k_actuator,cur) #print k_actuator,k_command QApplication.processEvents() time.sleep(.01) self.sensor.sense() x_mat[:,k_actuator,k_command] = self.sensor.x_slopes y_mat[:,k_actuator,k_command] = self.sensor.y_slopes self.finished.emit() # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat,axis=2) d_y_mat = np.diff(y_mat,axis=2) x_response = np.mean(d_x_mat/d_commands,axis=2) y_response = np.mean(d_y_mat/d_commands,axis=2) poke = np.vstack((x_response,y_response)) ns = now_string() # After we make a new poke matrix, we will save it in # two files: an archive file that can be used to keep # track of old poke matrices, and the file specified # in the config file, e.g., 'poke.txt'. # The archive filename will use the time date string # generated above. This filename will also be used to # save the commands and the mirror mode chart PDF. poke_fn = ccfg.poke_filename archive_poke_fn = os.path.join(ccfg.poke_directory,'%s_poke.txt'%ns) archive_command_fn = os.path.join(ccfg.poke_directory,'%s_currents.txt'%ns) archive_chart_fn = os.path.join(ccfg.poke_directory,'%s_modes.pdf'%ns) np.savetxt(poke_fn,poke) np.savetxt(archive_poke_fn,poke) np.savetxt(archive_command_fn,commands) save_modes_chart(archive_chart_fn,poke,commands,self.mirror.mirror_mask) self.poke = Poke(poke) self.close_ok = ccfg.loop_condition_llim<self.get_condition_number()<ccfg.loop_condition_ulim time.sleep(1) self.unpause() def set_closed(self,val): self.closed = val
class Loop(QObject): finished = pyqtSignal() pause_signal = pyqtSignal() unpause_signal = pyqtSignal() def __init__(self,sensor,mirror): super(Loop,self).__init__() self.mirror_thread = QThread() self.sensor_thread = QThread() self.sensor = sensor self.active_lenslets = np.ones(self.sensor.n_lenslets).astype(int) self.mirror = mirror n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators dummy = np.ones((2*n_lenslets,n_actuators)) outfn = os.path.join(kcfg.poke_directory,'dummy_poke.txt') np.savetxt(outfn,dummy) #DEBUG self.sensor.moveToThread(self.sensor_thread) self.mirror.moveToThread(self.mirror_thread) self.sensor_thread.started.connect(self.sensor.update) self.finished.connect(self.sensor.update) self.sensor.finished.connect(self.update) self.pause_signal.connect(self.sensor.pause) self.pause_signal.connect(self.mirror.pause) self.unpause_signal.connect(self.sensor.unpause) self.unpause_signal.connect(self.mirror.unpause) self.poke = None self.closed = False try: self.load_poke(kcfg.poke_filename) except Exception as e: self.load_poke() self.gain = kcfg.loop_gain self.loss = kcfg.loop_loss self.paused = False def has_poke(self): return self.poke is not None def start(self): self.sensor_thread.start() self.mirror_thread.start() def pause(self): self.pause_signal.emit() self.paused = True def unpause(self): self.unpause_signal.emit() self.paused = False self.finished.emit() print 'loop unpaused' @pyqtSlot() def update(self): if not self.paused: sensor_mutex.lock() mirror_mutex.lock() # compute the mirror command here if self.closed and self.has_poke(): current_active_lenslets = np.zeros(self.active_lenslets.shape) current_active_lenslets[np.where(self.sensor.box_maxes>kcfg.spots_threshold)] = 1 if not all(self.active_lenslets==current_active_lenslets): self.active_lenslets[:] = current_active_lenslets[:] self.poke.invert(mask=self.active_lenslets) xs = self.sensor.x_slopes[np.where(self.active_lenslets)[0]] ys = self.sensor.y_slopes[np.where(self.active_lenslets)[0]] slope_vec = np.hstack((xs,ys)) command = self.gain * np.dot(self.poke.ctrl,slope_vec) command = self.mirror.get_command()*(1-self.loss) - command self.mirror.set_command(command) self.finished.emit() sensor_mutex.unlock() mirror_mutex.unlock() def load_poke(self,poke_filename=None): sensor_mutex.lock() mirror_mutex.lock() try: poke = np.loadtxt(poke_filename) except Exception as e: error_message('Could not find %s.'%poke_filename) options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog poke_filename, _ = QFileDialog.getOpenFileName( None, "Please select a poke file.", kcfg.poke_directory, "Text Files (*.txt)", options=options) poke = np.loadtxt(poke_filename) py,px = poke.shape expected_py = self.sensor.n_lenslets*2 expected_px = self.mirror.n_actuators dummy = np.ones((expected_py,expected_px)) try: assert (py==expected_py and px==expected_px) except AssertionError as ae: error_message('Poke matrix has shape (%d,%d), but (%d,%d) was expected. Using dummy matrix.'%(py,px,expected_py,expected_px)) poke = dummy self.poke = Poke(poke) sensor_mutex.unlock() mirror_mutex.unlock() def invert(self): if self.poke is not None: self.pause() time.sleep(1) self.poke.invert() time.sleep(1) QApplication.processEvents() self.unpause() time.sleep(1) def set_n_modes(self,n): try: self.poke.n_modes = n except Exception as e: print e def get_n_modes(self): out = -1 try: out = self.poke.n_modes except Exception as e: print e return out def get_condition_number(self): out = -1 try: out = self.poke.cutoff_cond except Exception as e: print e return out def run_poke(self): cmin = kcfg.poke_command_min cmax = kcfg.poke_command_max n_commands = kcfg.poke_n_command_steps commands = np.linspace(cmin,cmax,n_commands) self.pause() time.sleep(1) n_lenslets = self.sensor.n_lenslets n_actuators = self.mirror.n_actuators x_mat = np.zeros((n_lenslets,n_actuators,n_commands)) y_mat = np.zeros((n_lenslets,n_actuators,n_commands)) for k_actuator in range(n_actuators): self.mirror.flatten() for k_command in range(n_commands): cur = commands[k_command] print k_actuator,cur self.mirror.set_actuator(k_actuator,cur) QApplication.processEvents() time.sleep(.01) self.sensor.sense() sensor_mutex.lock() x_mat[:,k_actuator,k_command] = self.sensor.x_slopes y_mat[:,k_actuator,k_command] = self.sensor.y_slopes sensor_mutex.unlock() self.finished.emit() # print 'done' self.mirror.flatten() d_commands = np.mean(np.diff(commands)) d_x_mat = np.diff(x_mat,axis=2) d_y_mat = np.diff(y_mat,axis=2) x_response = np.mean(d_x_mat/d_commands,axis=2) y_response = np.mean(d_y_mat/d_commands,axis=2) poke = np.vstack((x_response,y_response)) ns = now_string() poke_fn = os.path.join(kcfg.poke_directory,'%s_poke.txt'%ns) command_fn = os.path.join(kcfg.poke_directory,'%s_currents.txt'%ns) chart_fn = os.path.join(kcfg.poke_directory,'%s_modes.pdf'%ns) np.savetxt(poke_fn,poke) np.savetxt(command_fn,commands) save_modes_chart(chart_fn,poke,commands,self.mirror.mirror_mask) self.poke = Poke(poke) time.sleep(1) self.unpause() def set_closed(self,val): self.closed = val