def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[Protocol]._upgrade()") version = Version.fromstring(self.version) logger.debug('[Protocol] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[Protocol] version>class_version') raise FutureVersionError(Version.fromstring(self.class_version), version) elif version < Version.fromstring(self.class_version): if version < Version(0,1): for k, v in self.plugin_data.items(): self.plugin_data[k] = yaml.dump(v) for step in self.steps: for k, v in step.plugin_data.items(): step.plugin_data[k] = yaml.dump(v) self.version = str(Version(0,1)) logger.debug('[Protocol] upgrade to version %s' % self.version) if version < Version(0,2): self.current_step_attempt = 0 self.version = str(Version(0,2)) logger.debug('[Protocol] upgrade to version %s' % self.version)
def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[Protocol]._upgrade()") version = Version.fromstring(self.version) logger.debug('[Protocol] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[Protocol] version>class_version') raise FutureVersionError(Version.fromstring(self.class_version), version) elif version < Version.fromstring(self.class_version): if version < Version(0, 1): for k, v in self.plugin_data.items(): self.plugin_data[k] = yaml.dump(v) for step in self.steps: for k, v in step.plugin_data.items(): step.plugin_data[k] = yaml.dump(v) self.version = str(Version(0, 1)) logger.debug('[Protocol] upgrade to version %s' % self.version) if version < Version(0, 2): self.current_step_attempt = 0 self.version = str(Version(0, 2)) logger.debug('[Protocol] upgrade to version %s' % self.version)
def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger = _L() # use logger with method context version = Version.fromstring(self.version) logger.debug('version=%s, class_version=%s', str(version), self.class_version) if version > Version.fromstring(self.class_version): logger.debug('version > class_version') raise FutureVersionError(Version.fromstring(self.class_version), version) elif version < Version.fromstring(self.class_version): if version < Version(0, 1): for k, v in self.plugin_data.items(): self.plugin_data[k] = yaml.dump(v) for step in self.steps: for k, v in step.plugin_data.items(): step.plugin_data[k] = yaml.dump(v) self.version = str(Version(0, 1)) logger.debug('upgrade to version %s', self.version) if version < Version(0, 2): self.version = str(Version(0, 2)) logger.debug('upgrade to version %s', self.version)
def fit_hv_feedback_params(control_board, max_resistor_readings): ''' Fit model of control board high-voltage feed-back resistor and parasitic capacitance values based on measured voltage readings. ''' hardware_version = Version.fromstring(control_board .hardware_version()) R1 = 10e6 if hardware_version.major == 2: f = hv_transfer_function_v2 else: f = hv_transfer_function e = lambda p, x, y, R1: f(p, x, R1) - y def fit_resistor_params(x): resistor_index = x['resistor index'].values[0] x['attenuation'] = x['board measured V'] / x['oscope measured V'] p0 = [control_board.calibration.C_hv[resistor_index], control_board.calibration.R_hv[resistor_index]] p1, success = optimize.leastsq(e, p0, args=(x['frequency'], x['attenuation'], R1)) return pd.DataFrame([p0 + p1.tolist()], columns=['original C', 'original R', 'fitted C', 'fitted R']).T results = (max_resistor_readings [max_resistor_results['resistor index'] >= 0] .groupby(['resistor index']).apply(fit_resistor_params)) data = results.unstack() data.columns = data.columns.droplevel() return data
def test_load_protocol(): """ test loading protocol files """ # version 0.0.0 files for i in [0]: yield load_protocol, (path(__file__).parent / path('protocols') / path('protocol %d v%s' % (i, Version(0,0,0)))) # version 0.1.0 files for i in [0]: yield load_protocol, (path(__file__).parent / path('protocols') / path('protocol %d v%s' % (i, Version(0,1,0))))
def update_plugin(self, plugin_controller, verbose=False, force=False): app = get_app() server_url = app.get_app_value('server_url') plugin_metadata = plugin_controller.get_plugin_info() package_name = plugin_metadata.package_name plugin_name = plugin_metadata.plugin_name plugin_repo = PluginRepository(server_url) latest_version = Version(**plugin_repo .latest_version(package_name, app_version=APP_VERSION)) # Check the plugin tag versus the tag of latest version from the # update respository. If they are different, it's a sign that they # the currently installed plugin may be incompatible. if plugin_controller.version.tags != latest_version.tags: if yesno('The currently installed plugin (%s-%s) is from a ' 'different branch and may not be compatible with ' 'this version of MicroDrop. Would you like to download ' 'a compatible version?' % (plugin_name, plugin_controller.version) ) == gtk.RESPONSE_YES: return self.download_and_install_plugin(package_name, force=force) elif plugin_controller.version < latest_version: return self.download_and_install_plugin(package_name, force=force) else: message = 'Plugin %s is up to date (version %s)' % ( plugin_name, plugin_controller.version) if verbose: logging.warning(message) logging.info(message) return False
def create_feedback_calibration(self): logging.info("Poll control board for series resistors and " "capacitance values.") R_hv = [] C_hv = [] R_fb = [] C_fb = [] i = 0 while (self.set_series_resistor_index(0, i) == 0): R_hv.append(self.series_resistance(0)) C_hv.append(self.series_capacitance(0)) i += 1 logging.info("HV series resistors =% s" % R_hv) logging.info("HV series capacitance =% s" % C_hv) i = 0 while (self.set_series_resistor_index(1, i) == 0): R_fb.append(self.series_resistance(1)) C_fb.append(self.series_capacitance(1)) i += 1 logging.info("Feedback series resistors=%s" % R_fb) logging.info("Feedback series capacitance=%s" % C_fb) self.set_series_resistor_index(0, 0) self.set_series_resistor_index(1, 0) hardware_version = Version.fromstring(self.description() ['HARDWARE_VERSION']) calibration = FeedbackCalibration(R_hv, C_hv, R_fb, C_fb, hw_version=hardware_version) return calibration
class Protocol(): class_version = str(Version(0, 2)) def __init__(self, name=None): self.version = self.class_version self.name = name self.steps = [Step()] self.plugin_data = {} self.plugin_fields = {} # Protocol execution state self.n_repeats = 1 self.current_step_attempt = 0 self.current_step_number = 0 self.current_repetition = 0 ########################################################################### # Load/save methods # ----------------- @classmethod def load(cls, filename): """ Load a Protocol from a file. Parameters ---------- filename : str Path to file. Raises ------ TypeError If file is not a :class:`Protocol`. FutureVersionError If file was written by a future version of the software. """ logger = _L() # use logger with method context logger.info("Loading Protocol from %s" % filename) filename = ph.path(filename) if filename.ext.lower() == '.json': with filename.open('r') as input_: return cls.from_json(istream=input_) start_time = time.time() out = None with open(filename, 'rb') as f: try: out = pickle.load(f) logger.debug("Loaded object from pickle.") except Exception, e: logger.debug("Not a valid pickle file. %s." % e) if out is None: with open(filename, 'rb') as f: try: out = yaml.load(f) logger.debug("Loaded object from YAML file.") except Exception, e: logger.debug("Not a valid YAML file. %s." % e)
def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[ExperimentLog]._upgrade()") version = Version.fromstring(self.version) logger.debug('[ExperimentLog] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[ExperimentLog] version>class_version') raise FutureVersionError if version < Version(0, 1, 0): new_data = [] plugin_name = None for step_data in self.data: if "control board hardware version" in step_data.keys(): plugin_name = "wheelerlab.dmf_control_board_" + \ step_data["control board hardware version"] for i in range(len(self.data)): new_data.append({}) for k, v in self.data[i].items(): if plugin_name and (k=="FeedbackResults" or \ k=="SweepFrequencyResults" or k=="SweepVoltageResults"): try: new_data[i][plugin_name] = \ {k:pickle.loads(v)} except Exception, e: logger.error("Couldn't load experiment log data " "for plugin: %s. %s." % \ (plugin_name, e)) else: if not "core" in new_data[i]: new_data[i]["core"] = {} new_data[i]["core"][k] = v # serialize objects to yaml strings for i in range(len(self.data)): for plugin_name, plugin_data in new_data[i].items(): new_data[i][plugin_name] = yaml.dump(plugin_data) self.data = new_data self.version = str(Version(0, 1, 0))
def test_load_experiment_log(): """ test loading experiment log files """ # version 0.0.0 files for i in [0]: yield load_experiment_log, (path(__file__).parent / path('experiment_logs') / path('experiment log %d v%s' % (i, Version(0, 0, 0)))) # version 0.1.0 files for i in [0]: yield load_experiment_log, (path(__file__).parent / path('experiment_logs') / path('experiment log %d v%s' % (i, Version(0, 1, 0))))
def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[ExperimentLog]._upgrade()") version = Version.fromstring(self.version) logger.debug('[ExperimentLog] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[ExperimentLog] version>class_version') raise FutureVersionError if version < Version(0,1,0): new_data = [] plugin_name = None for step_data in self.data: if "control board hardware version" in step_data.keys(): plugin_name = "wheelerlab.dmf_control_board_" + \ step_data["control board hardware version"] for i in range(len(self.data)): new_data.append({}) for k, v in self.data[i].items(): if plugin_name and (k=="FeedbackResults" or \ k=="SweepFrequencyResults" or k=="SweepVoltageResults"): try: new_data[i][plugin_name] = \ {k:pickle.loads(v)} except Exception, e: logger.error("Couldn't load experiment log data " "for plugin: %s. %s." % \ (plugin_name, e)) else: if not "core" in new_data[i]: new_data[i]["core"] = {} new_data[i]["core"][k] = v # serialize objects to yaml strings for i in range(len(self.data)): for plugin_name, plugin_data in new_data[i].items(): new_data[i][plugin_name] = yaml.dump(plugin_data) self.data = new_data self.version = str(Version(0,1,0))
class DmfDevice(): class_version = str(Version(0, 3, 0)) def __init__(self): self.electrodes = {} self.x_min = np.Inf self.x_max = 0 self.y_min = np.Inf self.y_max = 0 self.name = None self.scale = None self.path_group = None # svg_model.path_group.PathGroup self.version = self.class_version self.electrode_name_map = {} self.name_electrode_map = {} @classmethod def load(cls, filename): """ Load a DmfDevice from a file. Args: filename (str) : Path to file. Raises: TypeError : File is not a DmfDevice. FutureVersionError : File was written by a future version of the software. """ logger.debug("[DmfDevice].load(\"%s\")" % filename) logger.info("Loading DmfDevice from %s" % filename) out = None # Assume file contains `pickle`-serialized device. with open(filename, 'rb') as f: try: out = pickle.load(f) logger.debug("Loaded object from pickle.") except Exception, e: logger.debug("Not a valid pickle file. %s." % e) # Assume file contains `pickle`-serialized device, but using # `microdrop.dmf_device` module. if out is None: device_data = path(filename).bytes() device_data = device_data.replace('microdrop.dmf_device', 'microdrop_device_converter' '.dmf_device') try: out = pickle.loads(device_data) logger.debug('Loaded object from pickle.') except Exception, e: logger.debug('Not a valid pickle file.', exc_info=True)
def get_hv_transfer_function(control_board): hardware_version = Version.fromstring(control_board .hardware_version()) R1 = 10e6 # Since the feed-back circuit changed in version 2 of the control board, we # use the transfer function that corresponds to the current control board # version that the fitted attenuation model is based on. if hardware_version.major == 2: f = hv_transfer_function_v2 else: f = hv_transfer_function return f
class Protocol(): class_version = str(Version(0, 2)) def __init__(self, name=None): self.steps = [Step()] self.name = None self.plugin_data = {} self.plugin_fields = {} self.n_repeats = 1 self.current_step_attempt = 0 self.current_step_number = 0 self.current_repetition = 0 self.version = self.class_version @classmethod def load(cls, filename): """ Load a Protocol from a file. Parameters ---------- filename : str Path to file. Raises ------ TypeError If file is not a :class:`Protocol`. FutureVersionError If file was written by a future version of the software. """ logger.debug("[Protocol].load(\"%s\")" % filename) logger.info("Loading Protocol from %s" % filename) start_time = time.time() out = None with open(filename, 'rb') as f: try: out = pickle.load(f) logger.debug("Loaded object from pickle.") except Exception, e: logger.debug("Not a valid pickle file. %s." % e) if out == None: with open(filename, 'rb') as f: try: out = yaml.load(f) logger.debug("Loaded object from YAML file.") except Exception, e: logger.debug("Not a valid YAML file. %s." % e)
def update_check(self): if self._update_setting() not in ('auto-update', 'check for updates, but ask before ' 'installing'): return app_update_server_url = self.config.data.get(self.name, {}).get( 'server_url', 'http://microfluidics.utoronto.ca/update') logger.debug('[APP UPDATE SERVER] server url: %s' % app_update_server_url) app_repository = AppRepository(app_update_server_url) current_version = Version.fromstring(self.version) try: latest_version = Version(**app_repository.latest_version('microdrop')) except (JSONRPCException, JSONDecodeException, IOError): logger.warning('Could not connect to application update server: ' '%s', app_update_server_url) return if current_version < latest_version: logger.info('Current version: %s. There is a new version ' 'available: %s %s' % (current_version, latest_version, app_repository.server_url + app_repository .latest_package_url( 'microdrop'))) response = yesno(''' There is a new version of Microdrop available (%s, current version: %s). Would you like to download the latest version in your browser?''' % (latest_version, current_version)) if response == gtk.RESPONSE_YES: latest_full_url = (app_repository.server_url + app_repository .latest_package_url('microdrop')) if webbrowser.open_new_tab(latest_full_url): logger.info('Closing app after opening browser to latest ' 'version (%s).' % latest_version) try: self.main_window_controller.on_destroy(None) except AttributeError: raise SystemExit, 'Closing app to allow upgrade installation' else: logger.info('[SUCCESS] software is up-to-date.\n (installed ' 'version: %s, server version: %s)' % (current_version, latest_version))
class ExperimentLog(): class_version = str(Version(0, 3, 0)) def __init__(self, directory=None): self.directory = directory self.data = [] self.version = self.class_version self.uuid = str(uuid.uuid4()) self._get_next_id() self.metadata = {} # Meta data, keyed by plugin name. logger.info('[ExperimentLog] new log with id=%s and uuid=%s' % (self.experiment_id, self.uuid)) def _get_next_id(self): if self.directory is None: self.experiment_id = None return if (os.path.isdir(self.directory) == False): os.makedirs(self.directory) logs = path(self.directory).listdir() self.experiment_id = 0 for d in logs: if is_int(d.name): i = int(d.name) if i >= self.experiment_id: self.experiment_id = i # increment the experiment_id if the current directory is not empty if len(d.listdir()): self.experiment_id += 1 log_path = self.get_log_path() if not log_path.isdir(): log_path.makedirs_p() def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[ExperimentLog]._upgrade()") version = Version.fromstring(self.version) logger.debug('[ExperimentLog] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[ExperimentLog] version>class_version') raise FutureVersionError if version < Version(0, 1, 0): new_data = [] plugin_name = None for step_data in self.data: if "control board hardware version" in step_data.keys(): plugin_name = "wheelerlab.dmf_control_board_" + \ step_data["control board hardware version"] for i in range(len(self.data)): new_data.append({}) for k, v in self.data[i].items(): if plugin_name and (k=="FeedbackResults" or \ k=="SweepFrequencyResults" or k=="SweepVoltageResults"): try: new_data[i][plugin_name] = \ {k:pickle.loads(v)} except Exception, e: logger.error("Couldn't load experiment log data " "for plugin: %s. %s." % \ (plugin_name, e)) else: if not "core" in new_data[i]: new_data[i]["core"] = {} new_data[i]["core"][k] = v # serialize objects to yaml strings for i in range(len(self.data)): for plugin_name, plugin_data in new_data[i].items(): new_data[i][plugin_name] = yaml.dump(plugin_data) self.data = new_data self.version = str(Version(0, 1, 0)) if version < Version(0, 2, 0): self.uuid = str(uuid.uuid4()) self.version = str(Version(0, 2, 0)) if version < Version(0, 3, 0): self.metadata = {} self.version = str(Version(0, 3, 0))
logger.debug("Not a valid pickle file. %s." % e) if out == None: with open(filename, 'rb') as f: try: out = yaml.load(f) logger.debug("Loaded object from YAML file.") except Exception, e: logger.debug("Not a valid YAML file. %s." % e) if out == None: raise TypeError out.filename = filename # check type if out.__class__ != cls: raise TypeError if not hasattr(out, 'version'): out.version = str(Version(0)) out._upgrade() # load objects from serialized strings for i in range(len(out.data)): for plugin_name, plugin_data in out.data[i].items(): try: out.data[i][plugin_name] = pickle.loads(plugin_data) except Exception, e: logger.debug("Not a valid pickle string (" "plugin: %s). %s." % (plugin_name, e)) try: out.data[i][plugin_name] = yaml.load(plugin_data) except Exception, e: logger.error("Couldn't load experiment log data for " "plugin: %s. %s." % (plugin_name, e)) logger.debug("[ExperimentLog].load() loaded in %f s." % \
import tarfile import yaml from microdrop_utility import Version from path_helpers import path package_name = 'device_info_plugin' plugin_name = 'wheelerlab.device_info_plugin' # create a version sting based on the git revision/branch version = str(Version.from_git_repository()) # write the 'properties.yml' file properties = { 'plugin_name': plugin_name, 'package_name': package_name, 'version': version } with open('properties.yml', 'w') as f: f.write(yaml.dump(properties)) # create the tar.gz plugin archive with tarfile.open("%s-%s.tar.gz" % (package_name, version), "w:gz") as tar: for name in [ '__init__.py', 'properties.yml', 'hooks', 'on_plugin_install.py' ]: tar.add(name) requirements_file = path(__file__).parent.joinpath('requirements.txt') if requirements_file.exists(): tar.add(requirements_file)
def _upgrade(self): """ Upgrade the serialized object if necessary. Raises: FutureVersionError: file was written by a future version of the software. """ logger.debug("[DmfDevice]._upgrade()") version = Version.fromstring(self.version) logger.debug('[DmfDevice] version=%s, class_version=%s' % (str(version), self.class_version)) if version > Version.fromstring(self.class_version): logger.debug('[DmfDevice] version>class_version') raise FutureVersionError elif version < Version.fromstring(self.class_version): if version < Version(0,1): self.version = str(Version(0,1)) self.scale = None logger.info('[DmfDevice] upgrade to version %s' % self.version) if version < Version(0,2): self.version = str(Version(0,2)) for id, e in self.electrodes.items(): if hasattr(e, "state"): del self.electrodes[id].state logger.info('[DmfDevice] upgrade to version %s' % self.version) if version < Version(0,3): # Upgrade to use pymunk self.version = str(Version(0,3)) x_min = min([e.x_min for e in self.electrodes.values()]) x_max = max([e.x_max for e in self.electrodes.values()]) y_min = min([e.y_min for e in self.electrodes.values()]) y_max = max([e.y_max for e in self.electrodes.values()]) boundary = Path([Loop([(x_min, y_min), (x_min, y_max), (x_max, y_max), (x_max, y_min)])]) traced_paths = {} tracer = LoopTracer() for id, e in self.electrodes.iteritems(): try: path_tuples = [] for command in e.path: keys_ok = True for k in ['command', 'x', 'y']: if k not in command: # Missing a parameter, skip keys_ok = False if not keys_ok: continue path_tuples.append( (command['command'], float(command['x']), float(command['y']))) path_tuples.append(('Z',)) loops = tracer.to_loops(path_tuples) p = ColoredPath(loops) p.color = (0, 0, 255) traced_paths[str(id)] = p except ParseError: pass except KeyError: pass path_group = PathGroup(traced_paths, boundary) electrodes = self.electrodes self.electrodes = {} self.add_path_group(path_group) for id, e in electrodes.iteritems(): if str(id) in self.name_electrode_map: eid = self.name_electrode_map[str(id)] self.electrodes[eid].channels = e.channels del electrodes logger.info('[DmfDevice] upgrade to version %s' % self.version)
def from_dict(data): package_name = data['package_name'] plugin_name = data['plugin_name'] version = Version.fromstring(data['version']) return PluginMetaData(package_name, plugin_name, version)
import tarfile import yaml from microdrop_utility import Version from path_helpers import path package_name = 'zmq_hub_plugin' plugin_name = 'wheelerlab.zmq_hub_plugin' # create a version sting based on the git revision/branch version = str(Version.from_git_repository()) # write the 'properties.yml' file properties = {'plugin_name': plugin_name, 'package_name': package_name, 'version': version} with open('properties.yml', 'w') as f: f.write(yaml.dump(properties)) # create the tar.gz plugin archive with tarfile.open("%s-%s.tar.gz" % (package_name, version), "w:gz") as tar: for name in ['__init__.py', 'properties.yml', 'hooks', 'on_plugin_install.py']: tar.add(name) requirements_file = path(__file__).parent.joinpath('requirements.txt') if requirements_file.exists(): tar.add(requirements_file)