Loading dstat_interface/interface/save.py +126 −150 Viewed Changes for dstat_interface/interface/save.py: 126 added lines, 150 removed lines. Original line number Diff line number Diff line #!/usr/bin/env python # -*- coding: utf-8 -*- # DStat Interface - An interface for the open hardware DStat potentiostat # Copyright (C) 2014 Michael D. M. Dryden - # Copyright (C) 2014 Michael D. M. Dryden - # Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> # # # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. Loading @@ -23,49 +23,42 @@ import os import gtk import numpy as np import logging from errors import InputError, VarError, ErrorLogger _logger = ErrorLogger(sender="dstat-interface-save") logger = logging.getLogger("dstat.interface.save") from errors import InputError, VarError from params import save_params, load_params def manSave(current_exp): fcd = gtk.FileChooserDialog("Save...", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) filters = [gtk.FileFilter()] filters[0].set_name("Space separated text (.txt)") filters[0].add_pattern("*.txt") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) filter_selection = fcd.get_filter().get_name() if filter_selection.endswith("(.npy)"): if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): npy(current_exp, current_exp.data, "-".join((path,'data'))) npy(current_exp, current_exp.ftdata, "-".join((path,'ft'))) else: npy(current_exp, current_exp.data, path, auto=True) elif filter_selection.endswith("(.txt)"): if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): text(current_exp, current_exp.data, "-".join((path,'data'))) text(current_exp, current_exp.ftdata, "-".join((path,'ft'))) else: text(current_exp, current_exp.data, path, auto=True) if filter_selection.endswith("(.txt)"): save_text(current_exp, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def plotSave(plots): def plot_save_dialog(plots): fcd = gtk.FileChooserDialog("Save Plot…", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, Loading @@ -77,37 +70,34 @@ def plotSave(plots): filters.append(gtk.FileFilter()) filters[1].set_name("Portable Network Graphics (.png)") filters[1].add_pattern("*.png") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) filter_selection = fcd.get_filter().get_name() for i in plots: save_path = path save_path += '-' save_path += i if filter_selection.endswith("(.pdf)"): if not path.endswith(".pdf"): path += ".pdf" elif filter_selection.endswith("(.png)"): if not path.endswith(".png"): path += ".png" if filter_selection.endswith("(.pdf)"): if not save_path.endswith(".pdf"): save_path += ".pdf" elif filter_selection.endswith("(.png)"): if not save_path.endswith(".png"): save_path += ".png" plots[i].figure.savefig(save_path) # determines format from file extension save_plot(plots, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def man_param_save(window): fcd = gtk.FileChooserDialog("Save Parameters…", None, Loading @@ -115,28 +105,28 @@ def man_param_save(window): (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK) ) filters = [gtk.FileFilter()] filters[0].set_name("Parameter File (.yml)") filters[0].add_pattern("*.yml") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) if not path.endswith(".yml"): path += '.yml' save_params(window, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() Loading @@ -147,136 +137,122 @@ def man_param_load(window): (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) filters = [gtk.FileFilter()] filters[0].set_name("Parameter File (.yml)") filters[0].add_pattern("*.yml") for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) load_params(window, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def autoSave(current_exp, dir_button, name, expnumber): def autoSave(exp, path, name): if name == "": name = "file" path = dir_button.get_filename() path += '/' path += name path += '-' path += str(expnumber) if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): text(current_exp, current_exp.data, "-".join((path,'data')), auto=True) text(current_exp, current_exp.ftdata, "-".join((path,'ft')), auto=True) else: text(current_exp, current_exp.data, path, auto=True) def autoPlot(plots, dir_button, name, expnumber): for i in plots: if name == "": name = "file" path = dir_button.get_filename() path += '/' path += name path += '-' path += str(expnumber) path += '-' path += i save_text(exp, path) def autoPlot(exp, path, name): if name == "": name = "file" if path.endswith(".pdf"): path = path.rstrip(".pdf") j = 1 while os.path.exists("".join([path, ".pdf"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 path += '/' path += name if not (path.endswith(".pdf") or path.endswith(".png")): path += ".pdf" plots[i].figure.savefig(path) def npy(exp, data, path, auto=False): if path.endswith(".npy"): path = path.rstrip(".npy") if auto == True: j = 1 while os.path.exists("".join([path, ".npy"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 np.save(path, data) save_plot(exp, path) def text(exp, data, path, auto=False): if path.endswith(".txt"): path = path.rstrip(".txt") def save_text(exp, path): name, _sep, ext = path.rpartition('.') # ('','',string) if no match if _sep == '': name = ext ext = 'txt' if auto == True: j = 1 while os.path.exists("".join([path, ".txt"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 num = '' j = 0 path += ".txt" file = open(path, 'w') for dname in exp.data: # Test for any existing files while os.path.exists("%s%s-%s.%s" % (name, num, dname, ext)): j += 1 num = j time = exp.time for dname in exp.data: # save data file = open("%s%s-%s.%s" % (name, num, dname, ext), 'w') header = "".join(['# TIME ', time.isoformat(), "\n"]) time = exp.time header = "".join(['# TIME ', time.isoformat(), "\n"]) header += "# DSTAT COMMANDS\n# " for i in exp.commands: header += i header += "# DSTAT COMMANDS\n# " for i in exp.commands: header += i file.write("".join([header, '\n'])) file.write("".join([header, '\n'])) analysis_buffer = [] analysis_buffer = [] if exp.analysis != {}: analysis_buffer.append("# ANALYSIS") for key, value in exp.analysis.iteritems(): analysis_buffer.append("# %s:" % key) for scan in value: number, result = scan analysis_buffer.append( "# Scan %s -- %s" % (number, result) ) if exp.analysis != {}: analysis_buffer.append("# ANALYSIS") for key, value in exp.analysis.iteritems(): analysis_buffer.append("# %s:" % key) for scan in value: number, result = scan analysis_buffer.append( "# Scan %s -- %s" % (number, result) ) for i in analysis_buffer: file.write("%s\n" % i) for i in analysis_buffer: file.write("%s\n" % i) # Write out actual data line_buffer = [] # Write out actual data line_buffer = [] for scan in zip(*data): for dimension in scan: for i in range(len(dimension)): try: line_buffer[i] += "%s " % dimension[i] except IndexError: line_buffer.append("") line_buffer[i] += "%s " % dimension[i] for scan in zip(*exp.data[dname]): for dimension in scan: for i in range(len(dimension)): try: line_buffer[i] += "%s " % dimension[i] except IndexError: line_buffer.append("") line_buffer[i] += "%s " % dimension[i] for i in line_buffer: file.write("%s\n" % i) for i in line_buffer: file.write("%s\n" % i) file.close() def save_plot(exp, path): """Saves everything in exp.plots to path. Appends a number for duplicates. If no file extension or unknown, uses pdf. """ name, _sep, ext = path.rpartition('.') if _sep == '': name = ext ext = 'pdf' num = '' j = 0 for i in exp.plots: # Test for any existing files while os.path.exists("%s%s-%s.%s" % (name, num, i, ext)): j += 1 num = j file.close() for i in exp.plots: # save data exp.plots[i].figure.savefig("%s%s-%s.%s" % (name, num, i, ext)) No newline at end of file dstat_interface/analysis.py +7 −7 Viewed Changes for dstat_interface/analysis.py: 7 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import pygtk import gtk from numpy import mean, trapz logger = logging.getLogger(__name__) logger = logging.getLogger('dstat.analysis') class AnalysisOptions(object): """Analysis options window.""" Loading Loading @@ -109,24 +109,24 @@ def do_analysis(experiment): if experiment.parameters['stats_start_true']: start = experiment.parameters['stats_start'] else: start = min(experiment.data[0][0]) start = min(experiment.data['data'][0][0]) if experiment.parameters['stats_stop_true']: stop = experiment.parameters['stats_stop'] else: stop = min(experiment.data[0][0]) stop = min(experiment.data['data'][0][0]) data = _data_slice(experiment.data, data = _data_slice(experiment.data['data'], start, stop ) else: data = experiment.data data = experiment.data['data'] experiment.analysis.update(_summary_stats(data)) try: x, y = experiment.ftdata[0] x, y = experiment.data['ft'][0] experiment.analysis['FT Integral'] = _integrateSpectrum( x, y, Loading @@ -134,7 +134,7 @@ def do_analysis(experiment): float(experiment.parameters['fft_int']) ) except AttributeError: except KeyError: pass def _data_slice(data, start, stop): Loading dstat_interface/build_windows.pydeleted 100644 → 0 +0 −30 Viewed Changes for dstat_interface/build_windows.py: 0 added lines, 30 removed lines. Original line number Diff line number Diff line #!/usr/bin/env python # DStat Interface - An interface for the open hardware DStat potentiostat # Copyright (C) 2014 Michael D. M. Dryden - # Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. __requires__ = 'PyInstaller==2.1' import os, sys os.chdir(os.path.dirname(sys.argv[0])) args = ['dstat.spec'] args.extend(sys.argv[1:]) import PyInstaller.main as pyi #For some reason, it gets the path here, so working dir must be set first pyi.run(args) dstat_interface/dstat_comm.py +45 −55 Viewed Changes for dstat_interface/dstat_comm.py: 45 added lines, 55 removed lines. Original line number Diff line number Diff line Loading @@ -22,13 +22,20 @@ from serial.tools import list_ports import time import struct import multiprocessing as mp from errors import InputError, VarError, ErrorLogger _logger = ErrorLogger(sender="dstat_comm") import logging from errors import InputError, VarError logger = logging.getLogger("dstat.comm") dstat_logger = logging.getLogger("dstat.comm.DSTAT") exp_logger = logging.getLogger("dstat.comm.Experiment") def _serial_process(ser_port, proc_pipe, ctrl_pipe, data_pipe): ser_logger = logging.getLogger("dstat.comm._serial_process") ser = delayedSerial(ser_port, baudrate=1000000, timeout=1) _logger.error("_serial_process() Connecting", 'INFO') ser_logger.info("Connecting") ser.write("ck") Loading @@ -50,23 +57,20 @@ def _serial_process(ser_port, proc_pipe, ctrl_pipe, data_pipe): if ctrl_buffer == ('a' or "DISCONNECT"): proc_pipe.send("ABORT") ser.write('a') _logger.error("_serial_process(): ABORT", 'INFO') ser_logger.info("ABORT") if ctrl_buffer == "DISCONNECT": _logger.error("_serial_process(): DISCONNECT", 'INFO') ser_logger.info("DISCONNECT") ser.close() proc_pipe.send("DISCONNECT") return False elif proc_pipe.poll(): while ctrl_pipe.poll(): ctrl_pipe.recv() return_code = proc_pipe.recv().run(ser, ctrl_pipe, data_pipe) e = "_serial_process: " e += str(return_code) _logger.error(e,'INFO') ser_logger.info('Return code: %s', str(return_code)) proc_pipe.send(return_code) Loading Loading @@ -104,27 +108,24 @@ class VersionCheck: if line.startswith('V'): input = line.lstrip('V') elif line.startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) ser.flushInput() break parted = input.rstrip().split('.') e = "DStat PCB version: " e = "PCB version: " e += str(input.rstrip()) _logger.error(e, "INFO") dstat_logger.info(e) data_pipe.send((int(parted[0]), int(parted[1]))) status = "DONE" except UnboundLocalError as e: _logger.error(e, "ERR") status = "SERIAL_ERROR" except SerialException as e: _logger.error(e, "ERR") logger.error('SerialException: %s', e) status = "SERIAL_ERROR" finally: Loading @@ -147,7 +148,7 @@ def version_check(ser_port): buffer = 1 else: buffer = serial_instance.data_pipe_p.recv() _logger.error("version_check done", "DBG") logger.debug("version_check done") return buffer Loading Loading @@ -191,11 +192,9 @@ class Settings: if line.lstrip().startswith('S'): input = line.lstrip().lstrip('S') elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.ser.flushInput() break Loading Loading @@ -240,8 +239,7 @@ def read_settings(): serial_instance.proc_pipe_p.send(Settings(task='r')) settings = serial_instance.data_pipe_p.recv() _logger.error("".join(("read_settings: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.debug("read_settings: %s", serial_instance.proc_pipe_p.recv()) return Loading @@ -254,8 +252,7 @@ def write_settings(): serial_instance.proc_pipe_p.send(Settings(task='w', settings=settings)) _logger.error("".join(("write_settings: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.debug("write_settings: %s", serial_instance.proc_pipe_p.recv()) return Loading @@ -281,11 +278,9 @@ class LightSensor: if line.lstrip().startswith('T'): input = line.lstrip().lstrip('T') elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) ser.flushInput() break Loading @@ -306,8 +301,7 @@ def read_light_sensor(): serial_instance.proc_pipe_p.send(LightSensor()) _logger.error("".join(("read_light_sensor: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.info("read_light_sensor: %s", serial_instance.proc_pipe_p.recv()) return serial_instance.data_pipe_p.recv() Loading @@ -328,7 +322,7 @@ class SerialDevices(object): self.ports, _, _ = zip(*list_ports.comports()) except ValueError: self.ports = [] _logger.error("No serial ports found", "ERR") logger.error("No serial ports found") def refresh(self): """Refreshes list of ports.""" Loading @@ -345,9 +339,11 @@ class Experiment(object): self.databytes = 8 self.scan = 0 self.time = 0 self.plots = {} self.data = {} # list of scans, tuple of dimensions, list of data self.data = [([], [])] self.data['data'] = [([], [])] self.line_data = ([], []) major, minor = self.parameters['version'] Loading Loading @@ -392,14 +388,14 @@ class Experiment(object): self.ctrl_pipe = ctrl_pipe self.data_pipe = data_pipe _logger.error("Experiment running", "INFO") exp_logger.info("Experiment running") try: self.serial.flushInput() status = "DONE" for i in self.commands: _logger.error("".join(("Command: ",i)), "INFO") logger.info("Command: %s", i) self.serial.write('!') while not self.serial.read().startswith("C"): Loading Loading @@ -427,17 +423,17 @@ class Experiment(object): while True: if self.ctrl_pipe.poll(): input = self.ctrl_pipe.recv() _logger.error("".join(("serial_handler: ", input)),"DBG") logger.debug("serial_handler: %s", input) if input == ('a' or "DISCONNECT"): self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False for line in self.serial: if self.ctrl_pipe.poll(): if self.ctrl_pipe.recv() == 'a': self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False if line.startswith('B'): Loading @@ -449,12 +445,10 @@ class Experiment(object): scan += 1 elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.serial.flushInput() return True Loading Loading @@ -509,17 +503,17 @@ class CALExp(Experiment): while True: if self.ctrl_pipe.poll(): input = self.ctrl_pipe.recv() _logger.error("".join(("serial_handler: ", input))) logger.debug("serial_handler: %s", input) if input == ('a' or "DISCONNECT"): self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False for line in self.serial: if self.ctrl_pipe.poll(): if self.ctrl_pipe.recv() == 'a': self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False if line.startswith('B'): Loading @@ -527,12 +521,10 @@ class CALExp(Experiment): self.serial.read(size=self.databytes))) elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.serial.flushInput() return True Loading Loading @@ -753,7 +745,7 @@ class SWVExp(Experiment): self.datatype = "SWVData" self.xlabel = "Voltage (mV)" self.ylabel = "Current (A)" self.data = [([], [], [], [])] # voltage, current, forwards, reverse self.data['data'] = [([], [], [], [])] # voltage, current, forwards, reverse self.line_data = ([], [], [], []) self.datalength = 2 * self.parameters['scans'] self.databytes = 10 Loading Loading @@ -812,7 +804,7 @@ class DPVExp(SWVExp): self.datatype = "SWVData" self.xlabel = "Voltage (mV)" self.ylabel = "Current (A)" self.data = [([], [], [], [])] # voltage, current, forwards, reverse self.data['data'] = [([], [], [], [])] # voltage, current, forwards, reverse self.line_data = ([], [], [], []) self.datalength = 2 self.databytes = 10 Loading Loading @@ -889,9 +881,7 @@ def measure_offset(time): for i in range(1,8): parameters['gain'] = i serial_instance.proc_pipe_p.send(CALExp(parameters)) _logger.error("".join( ("measure_offset: ", serial_instance.proc_pipe_p.recv())), "INFO") logger.info("measure_offset: %s", serial_instance.proc_pipe_p.recv()) gain_offset[gain_trim_table[i]] = serial_instance.data_pipe_p.recv() return gain_offset No newline at end of file dstat_interface/main.py +0 −0 Viewed File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
dstat_interface/interface/save.py +126 −150 Viewed Changes for dstat_interface/interface/save.py: 126 added lines, 150 removed lines. Original line number Diff line number Diff line #!/usr/bin/env python # -*- coding: utf-8 -*- # DStat Interface - An interface for the open hardware DStat potentiostat # Copyright (C) 2014 Michael D. M. Dryden - # Copyright (C) 2014 Michael D. M. Dryden - # Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> # # # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. Loading @@ -23,49 +23,42 @@ import os import gtk import numpy as np import logging from errors import InputError, VarError, ErrorLogger _logger = ErrorLogger(sender="dstat-interface-save") logger = logging.getLogger("dstat.interface.save") from errors import InputError, VarError from params import save_params, load_params def manSave(current_exp): fcd = gtk.FileChooserDialog("Save...", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) filters = [gtk.FileFilter()] filters[0].set_name("Space separated text (.txt)") filters[0].add_pattern("*.txt") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) filter_selection = fcd.get_filter().get_name() if filter_selection.endswith("(.npy)"): if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): npy(current_exp, current_exp.data, "-".join((path,'data'))) npy(current_exp, current_exp.ftdata, "-".join((path,'ft'))) else: npy(current_exp, current_exp.data, path, auto=True) elif filter_selection.endswith("(.txt)"): if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): text(current_exp, current_exp.data, "-".join((path,'data'))) text(current_exp, current_exp.ftdata, "-".join((path,'ft'))) else: text(current_exp, current_exp.data, path, auto=True) if filter_selection.endswith("(.txt)"): save_text(current_exp, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def plotSave(plots): def plot_save_dialog(plots): fcd = gtk.FileChooserDialog("Save Plot…", None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, Loading @@ -77,37 +70,34 @@ def plotSave(plots): filters.append(gtk.FileFilter()) filters[1].set_name("Portable Network Graphics (.png)") filters[1].add_pattern("*.png") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) filter_selection = fcd.get_filter().get_name() for i in plots: save_path = path save_path += '-' save_path += i if filter_selection.endswith("(.pdf)"): if not path.endswith(".pdf"): path += ".pdf" elif filter_selection.endswith("(.png)"): if not path.endswith(".png"): path += ".png" if filter_selection.endswith("(.pdf)"): if not save_path.endswith(".pdf"): save_path += ".pdf" elif filter_selection.endswith("(.png)"): if not save_path.endswith(".png"): save_path += ".png" plots[i].figure.savefig(save_path) # determines format from file extension save_plot(plots, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def man_param_save(window): fcd = gtk.FileChooserDialog("Save Parameters…", None, Loading @@ -115,28 +105,28 @@ def man_param_save(window): (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK) ) filters = [gtk.FileFilter()] filters[0].set_name("Parameter File (.yml)") filters[0].add_pattern("*.yml") fcd.set_do_overwrite_confirmation(True) for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) if not path.endswith(".yml"): path += '.yml' save_params(window, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() Loading @@ -147,136 +137,122 @@ def man_param_load(window): (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK) ) filters = [gtk.FileFilter()] filters[0].set_name("Parameter File (.yml)") filters[0].add_pattern("*.yml") for i in filters: fcd.add_filter(i) response = fcd.run() if response == gtk.RESPONSE_OK: path = fcd.get_filename() _logger.error(" ".join(("Selected filepath:", path)),'INFO') logger.info("Selected filepath: %s", path) load_params(window, path) fcd.destroy() elif response == gtk.RESPONSE_CANCEL: fcd.destroy() def autoSave(current_exp, dir_button, name, expnumber): def autoSave(exp, path, name): if name == "": name = "file" path = dir_button.get_filename() path += '/' path += name path += '-' path += str(expnumber) if (current_exp.parameters['shutter_true'] and current_exp.parameters['sync_true']): text(current_exp, current_exp.data, "-".join((path,'data')), auto=True) text(current_exp, current_exp.ftdata, "-".join((path,'ft')), auto=True) else: text(current_exp, current_exp.data, path, auto=True) def autoPlot(plots, dir_button, name, expnumber): for i in plots: if name == "": name = "file" path = dir_button.get_filename() path += '/' path += name path += '-' path += str(expnumber) path += '-' path += i save_text(exp, path) def autoPlot(exp, path, name): if name == "": name = "file" if path.endswith(".pdf"): path = path.rstrip(".pdf") j = 1 while os.path.exists("".join([path, ".pdf"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 path += '/' path += name if not (path.endswith(".pdf") or path.endswith(".png")): path += ".pdf" plots[i].figure.savefig(path) def npy(exp, data, path, auto=False): if path.endswith(".npy"): path = path.rstrip(".npy") if auto == True: j = 1 while os.path.exists("".join([path, ".npy"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 np.save(path, data) save_plot(exp, path) def text(exp, data, path, auto=False): if path.endswith(".txt"): path = path.rstrip(".txt") def save_text(exp, path): name, _sep, ext = path.rpartition('.') # ('','',string) if no match if _sep == '': name = ext ext = 'txt' if auto == True: j = 1 while os.path.exists("".join([path, ".txt"])): if j > 1: path = path[:-len(str(j))] path += str(j) j += 1 num = '' j = 0 path += ".txt" file = open(path, 'w') for dname in exp.data: # Test for any existing files while os.path.exists("%s%s-%s.%s" % (name, num, dname, ext)): j += 1 num = j time = exp.time for dname in exp.data: # save data file = open("%s%s-%s.%s" % (name, num, dname, ext), 'w') header = "".join(['# TIME ', time.isoformat(), "\n"]) time = exp.time header = "".join(['# TIME ', time.isoformat(), "\n"]) header += "# DSTAT COMMANDS\n# " for i in exp.commands: header += i header += "# DSTAT COMMANDS\n# " for i in exp.commands: header += i file.write("".join([header, '\n'])) file.write("".join([header, '\n'])) analysis_buffer = [] analysis_buffer = [] if exp.analysis != {}: analysis_buffer.append("# ANALYSIS") for key, value in exp.analysis.iteritems(): analysis_buffer.append("# %s:" % key) for scan in value: number, result = scan analysis_buffer.append( "# Scan %s -- %s" % (number, result) ) if exp.analysis != {}: analysis_buffer.append("# ANALYSIS") for key, value in exp.analysis.iteritems(): analysis_buffer.append("# %s:" % key) for scan in value: number, result = scan analysis_buffer.append( "# Scan %s -- %s" % (number, result) ) for i in analysis_buffer: file.write("%s\n" % i) for i in analysis_buffer: file.write("%s\n" % i) # Write out actual data line_buffer = [] # Write out actual data line_buffer = [] for scan in zip(*data): for dimension in scan: for i in range(len(dimension)): try: line_buffer[i] += "%s " % dimension[i] except IndexError: line_buffer.append("") line_buffer[i] += "%s " % dimension[i] for scan in zip(*exp.data[dname]): for dimension in scan: for i in range(len(dimension)): try: line_buffer[i] += "%s " % dimension[i] except IndexError: line_buffer.append("") line_buffer[i] += "%s " % dimension[i] for i in line_buffer: file.write("%s\n" % i) for i in line_buffer: file.write("%s\n" % i) file.close() def save_plot(exp, path): """Saves everything in exp.plots to path. Appends a number for duplicates. If no file extension or unknown, uses pdf. """ name, _sep, ext = path.rpartition('.') if _sep == '': name = ext ext = 'pdf' num = '' j = 0 for i in exp.plots: # Test for any existing files while os.path.exists("%s%s-%s.%s" % (name, num, i, ext)): j += 1 num = j file.close() for i in exp.plots: # save data exp.plots[i].figure.savefig("%s%s-%s.%s" % (name, num, i, ext)) No newline at end of file
dstat_interface/analysis.py +7 −7 Viewed Changes for dstat_interface/analysis.py: 7 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import pygtk import gtk from numpy import mean, trapz logger = logging.getLogger(__name__) logger = logging.getLogger('dstat.analysis') class AnalysisOptions(object): """Analysis options window.""" Loading Loading @@ -109,24 +109,24 @@ def do_analysis(experiment): if experiment.parameters['stats_start_true']: start = experiment.parameters['stats_start'] else: start = min(experiment.data[0][0]) start = min(experiment.data['data'][0][0]) if experiment.parameters['stats_stop_true']: stop = experiment.parameters['stats_stop'] else: stop = min(experiment.data[0][0]) stop = min(experiment.data['data'][0][0]) data = _data_slice(experiment.data, data = _data_slice(experiment.data['data'], start, stop ) else: data = experiment.data data = experiment.data['data'] experiment.analysis.update(_summary_stats(data)) try: x, y = experiment.ftdata[0] x, y = experiment.data['ft'][0] experiment.analysis['FT Integral'] = _integrateSpectrum( x, y, Loading @@ -134,7 +134,7 @@ def do_analysis(experiment): float(experiment.parameters['fft_int']) ) except AttributeError: except KeyError: pass def _data_slice(data, start, stop): Loading
dstat_interface/build_windows.pydeleted 100644 → 0 +0 −30 Viewed Changes for dstat_interface/build_windows.py: 0 added lines, 30 removed lines. Original line number Diff line number Diff line #!/usr/bin/env python # DStat Interface - An interface for the open hardware DStat potentiostat # Copyright (C) 2014 Michael D. M. Dryden - # Wheeler Microfluidics Laboratory <http://microfluidics.utoronto.ca> # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. __requires__ = 'PyInstaller==2.1' import os, sys os.chdir(os.path.dirname(sys.argv[0])) args = ['dstat.spec'] args.extend(sys.argv[1:]) import PyInstaller.main as pyi #For some reason, it gets the path here, so working dir must be set first pyi.run(args)
dstat_interface/dstat_comm.py +45 −55 Viewed Changes for dstat_interface/dstat_comm.py: 45 added lines, 55 removed lines. Original line number Diff line number Diff line Loading @@ -22,13 +22,20 @@ from serial.tools import list_ports import time import struct import multiprocessing as mp from errors import InputError, VarError, ErrorLogger _logger = ErrorLogger(sender="dstat_comm") import logging from errors import InputError, VarError logger = logging.getLogger("dstat.comm") dstat_logger = logging.getLogger("dstat.comm.DSTAT") exp_logger = logging.getLogger("dstat.comm.Experiment") def _serial_process(ser_port, proc_pipe, ctrl_pipe, data_pipe): ser_logger = logging.getLogger("dstat.comm._serial_process") ser = delayedSerial(ser_port, baudrate=1000000, timeout=1) _logger.error("_serial_process() Connecting", 'INFO') ser_logger.info("Connecting") ser.write("ck") Loading @@ -50,23 +57,20 @@ def _serial_process(ser_port, proc_pipe, ctrl_pipe, data_pipe): if ctrl_buffer == ('a' or "DISCONNECT"): proc_pipe.send("ABORT") ser.write('a') _logger.error("_serial_process(): ABORT", 'INFO') ser_logger.info("ABORT") if ctrl_buffer == "DISCONNECT": _logger.error("_serial_process(): DISCONNECT", 'INFO') ser_logger.info("DISCONNECT") ser.close() proc_pipe.send("DISCONNECT") return False elif proc_pipe.poll(): while ctrl_pipe.poll(): ctrl_pipe.recv() return_code = proc_pipe.recv().run(ser, ctrl_pipe, data_pipe) e = "_serial_process: " e += str(return_code) _logger.error(e,'INFO') ser_logger.info('Return code: %s', str(return_code)) proc_pipe.send(return_code) Loading Loading @@ -104,27 +108,24 @@ class VersionCheck: if line.startswith('V'): input = line.lstrip('V') elif line.startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) ser.flushInput() break parted = input.rstrip().split('.') e = "DStat PCB version: " e = "PCB version: " e += str(input.rstrip()) _logger.error(e, "INFO") dstat_logger.info(e) data_pipe.send((int(parted[0]), int(parted[1]))) status = "DONE" except UnboundLocalError as e: _logger.error(e, "ERR") status = "SERIAL_ERROR" except SerialException as e: _logger.error(e, "ERR") logger.error('SerialException: %s', e) status = "SERIAL_ERROR" finally: Loading @@ -147,7 +148,7 @@ def version_check(ser_port): buffer = 1 else: buffer = serial_instance.data_pipe_p.recv() _logger.error("version_check done", "DBG") logger.debug("version_check done") return buffer Loading Loading @@ -191,11 +192,9 @@ class Settings: if line.lstrip().startswith('S'): input = line.lstrip().lstrip('S') elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.ser.flushInput() break Loading Loading @@ -240,8 +239,7 @@ def read_settings(): serial_instance.proc_pipe_p.send(Settings(task='r')) settings = serial_instance.data_pipe_p.recv() _logger.error("".join(("read_settings: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.debug("read_settings: %s", serial_instance.proc_pipe_p.recv()) return Loading @@ -254,8 +252,7 @@ def write_settings(): serial_instance.proc_pipe_p.send(Settings(task='w', settings=settings)) _logger.error("".join(("write_settings: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.debug("write_settings: %s", serial_instance.proc_pipe_p.recv()) return Loading @@ -281,11 +278,9 @@ class LightSensor: if line.lstrip().startswith('T'): input = line.lstrip().lstrip('T') elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) ser.flushInput() break Loading @@ -306,8 +301,7 @@ def read_light_sensor(): serial_instance.proc_pipe_p.send(LightSensor()) _logger.error("".join(("read_light_sensor: ", serial_instance.proc_pipe_p.recv())),'DBG') logger.info("read_light_sensor: %s", serial_instance.proc_pipe_p.recv()) return serial_instance.data_pipe_p.recv() Loading @@ -328,7 +322,7 @@ class SerialDevices(object): self.ports, _, _ = zip(*list_ports.comports()) except ValueError: self.ports = [] _logger.error("No serial ports found", "ERR") logger.error("No serial ports found") def refresh(self): """Refreshes list of ports.""" Loading @@ -345,9 +339,11 @@ class Experiment(object): self.databytes = 8 self.scan = 0 self.time = 0 self.plots = {} self.data = {} # list of scans, tuple of dimensions, list of data self.data = [([], [])] self.data['data'] = [([], [])] self.line_data = ([], []) major, minor = self.parameters['version'] Loading Loading @@ -392,14 +388,14 @@ class Experiment(object): self.ctrl_pipe = ctrl_pipe self.data_pipe = data_pipe _logger.error("Experiment running", "INFO") exp_logger.info("Experiment running") try: self.serial.flushInput() status = "DONE" for i in self.commands: _logger.error("".join(("Command: ",i)), "INFO") logger.info("Command: %s", i) self.serial.write('!') while not self.serial.read().startswith("C"): Loading Loading @@ -427,17 +423,17 @@ class Experiment(object): while True: if self.ctrl_pipe.poll(): input = self.ctrl_pipe.recv() _logger.error("".join(("serial_handler: ", input)),"DBG") logger.debug("serial_handler: %s", input) if input == ('a' or "DISCONNECT"): self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False for line in self.serial: if self.ctrl_pipe.poll(): if self.ctrl_pipe.recv() == 'a': self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False if line.startswith('B'): Loading @@ -449,12 +445,10 @@ class Experiment(object): scan += 1 elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.serial.flushInput() return True Loading Loading @@ -509,17 +503,17 @@ class CALExp(Experiment): while True: if self.ctrl_pipe.poll(): input = self.ctrl_pipe.recv() _logger.error("".join(("serial_handler: ", input))) logger.debug("serial_handler: %s", input) if input == ('a' or "DISCONNECT"): self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False for line in self.serial: if self.ctrl_pipe.poll(): if self.ctrl_pipe.recv() == 'a': self.serial.write('a') _logger.error("serial_handler: ABORT pressed!","INFO") logger.info("serial_handler: ABORT pressed!") return False if line.startswith('B'): Loading @@ -527,12 +521,10 @@ class CALExp(Experiment): self.serial.read(size=self.databytes))) elif line.lstrip().startswith("#"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "INFO") dstat_logger.info(line.lstrip().rstrip()) elif line.lstrip().startswith("no"): _logger.error("".join( ("DSTAT: ",line.lstrip().rstrip())), "DBG") dstat_logger.debug(line.lstrip().rstrip()) self.serial.flushInput() return True Loading Loading @@ -753,7 +745,7 @@ class SWVExp(Experiment): self.datatype = "SWVData" self.xlabel = "Voltage (mV)" self.ylabel = "Current (A)" self.data = [([], [], [], [])] # voltage, current, forwards, reverse self.data['data'] = [([], [], [], [])] # voltage, current, forwards, reverse self.line_data = ([], [], [], []) self.datalength = 2 * self.parameters['scans'] self.databytes = 10 Loading Loading @@ -812,7 +804,7 @@ class DPVExp(SWVExp): self.datatype = "SWVData" self.xlabel = "Voltage (mV)" self.ylabel = "Current (A)" self.data = [([], [], [], [])] # voltage, current, forwards, reverse self.data['data'] = [([], [], [], [])] # voltage, current, forwards, reverse self.line_data = ([], [], [], []) self.datalength = 2 self.databytes = 10 Loading Loading @@ -889,9 +881,7 @@ def measure_offset(time): for i in range(1,8): parameters['gain'] = i serial_instance.proc_pipe_p.send(CALExp(parameters)) _logger.error("".join( ("measure_offset: ", serial_instance.proc_pipe_p.recv())), "INFO") logger.info("measure_offset: %s", serial_instance.proc_pipe_p.recv()) gain_offset[gain_trim_table[i]] = serial_instance.data_pipe_p.recv() return gain_offset No newline at end of file
dstat_interface/main.py +0 −0 Viewed File changed.Preview size limit exceeded, changes collapsed. Show changes