From: W. Trevor King Date: Thu, 11 Oct 2012 22:19:34 +0000 (-0400) Subject: gyang_curve.py: reader for LabVIEW unfolding experiments. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4bb1ab78aff5d6b68c45d3ee3acd3eef62a219b5;p=blog.git gyang_curve.py: reader for LabVIEW unfolding experiments. --- diff --git a/posts/Comparing_velocity_clamp_experiments/gyang_curve.py b/posts/Comparing_velocity_clamp_experiments/gyang_curve.py new file mode 100755 index 0000000..310e514 --- /dev/null +++ b/posts/Comparing_velocity_clamp_experiments/gyang_curve.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python2 +# +# Copyright (C) 2012 W. Trevor King +# +# 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 . + +"""Load pulling data from Prof. Yang's LabVIEW puller. +""" + +import datetime as _datetime +import os as _os +import re as _re +import time as _time + +from matplotlib import pyplot as _pyplot +import numpy as _numpy +from igor.binarywave import load as _load_ibw + + +class Curve (object): + _filename_regexp = _re.compile('^([A-Z][a-z]{2}[0-9]{2})_([0-9]+).ibw$') + _auxiliary_files = [ + 'par', + 'piz', + 'Vz', 'can', 'temp', 'time'] + _attribute_units = { + 'series': None, + 'trace': None, + 'z piezo sensitivity': 'V/m', + 'z input gain': None, + 'approach speed': 'm/s', + 'setpoint voltage': 'V', + 'sleep': 's', + 'pull range': 'm', + 'pull speed': 'm/s', + 'step size': 'm', + 'num steps': None, + 'points per step': None, + 'piezo': 'bits', + 'piezo expanded': 'bits', + 'deflection': 'bits', + 'back': 'm', + } + + _attributes = [ + 'series', + 'trace', + 'z piezo sensitivity', + 'z input gain', + 'approach speed', + 'setpoint voltage', + 'sleep', + 'pull range', + 'pull speed', + 'step size', + 'num steps', + 'points per step', + 'back', + ] + + def __init__(self, path, trace=0): + self.path = path + self.trace = trace + self._process_path() + self._load() + + def _process_path(self): + dirname,filename = _os.path.split(self.path) + match = self._filename_regexp.match(filename) + month_day,series = match.groups() + time = _time.strptime(month_day, '%b%d') + self.month = time.tm_mon + self.day = time.tm_mday + self.series = int(series) + self._auxiliary_paths = dict( + (aux, + _os.path.join( + dirname, 'params', '{}{}_{}'.format( + month_day, aux, series))) + for aux in self._auxiliary_files) + + def _load(self): + for aux in self._auxiliary_files: + loader = getattr(self, '_load_{}'.format(aux.lower())) + data = _load_ibw(self._auxiliary_paths[aux]) + loader(data=data) + data = _load_ibw(self.path) + self._load_deflection(data=data) + + def _load_par(self, data): + (series,pull_range,pull_speed,self.num_steps,self.points_per_step, + self.setpoint_voltage,self.sleep,step_size,back,approach_speed, + z_piezo_sensitivity,self.z_input_gain + ) = data['wave']['wData'] + assert series == self.series, (series, self.series) + self.pull_range = pull_range * 1e-9 # convert nm -> m + self.pull_speed = pull_speed * 1e-9 # convert nm/s -> m/s + self.step_size = step_size * 1e-9 # convert nm -> m + self.back = back * 1e-9 # convert nm -> m + self.approach_speed = approach_speed * 1e-9 # convert nm/s -> m/s + # convert nm/V -> V/m + self.z_piezo_sensitivity = 1e9 / z_piezo_sensitivity + + def _load_piz(self, data): + start = self.trace * self.num_steps + stop = (self.trace+1) * self.num_steps + self.piezo = data['wave']['wData'][start:stop] + self.piezo_expanded = _numpy.concatenate( + [[p]*self.points_per_step for p in self.piezo]) + self.traces = int(len(data['wave']['wData']) / self.num_steps) + + def _load_vz(self, data): + pass + + def _load_can(self, data): + pass + + def _load_temp(self, data): + #print(data['wave']['wData']) + pass + + def _load_time(self, data): + offset = 3070632000 # saved time = time since 1904 - offset + index = self.traces - self.trace + time_since_1904 = data['wave']['wData'][-index] + offset + # LabVIEW's `Get Date/Time In Seconds` returns seconds since + # 1904-01-01T00:00:00Z. + dt_1904 = _datetime.datetime(1904, 01, 01, 0, 0, 0) + dt_1970 = _datetime.datetime(1970, 01, 01, 0, 0, 0) + delta = (dt_1970 - dt_1904).total_seconds() + time_since_1970 = time_since_1904 - delta + # Unix time is measured from 1970-01-01T00:00:00Z + self.time_seconds = time_since_1970 + self.time = _time.gmtime(time_since_1970) + # ISO 8601 + self.time_iso = _time.strftime('%Y-%m-%dT%H:%M:%S%Z', self.time) + + def _load_deflection(self, data): + points = self.num_steps * self.points_per_step + start = self.trace * points + stop = (self.trace+1) * points + self.deflection = data['wave']['wData'][start:stop] + + def get_attribute(self, name): + return name.replace(' ', '_') + + def get_attribute_name(self, attribute): + return attribute.replace('_', ' ') + + def get_attribute_units(self, attribute): + name = self.get_attribute_name(attribute) + return self._attribute_units.get(name, None) + + def dumps(self): + lines = ['time = {} ({})'.format(self.time_iso, self.time_seconds)] + for name in self._attributes: + attr = self.get_attribute(name) + value = getattr(self, attr) + units = self.get_attribute_units(attr) + if units: + lines.append('{} = {} {}'.format(name, value, units)) + else: + lines.append('{} = {}'.format(name, value)) + return '\n'.join(lines) + + def plot(self): + figure = _pyplot.figure() + axes = figure.add_subplot(1, 1, 1) + axes.plot(self.piezo_expanded, self.deflection, 'b.') + + +def load_all_traces(path): + curve = Curve(path=path) + yield curve + for trace in range(1, curve.traces): + yield Curve(path=path, trace=trace) + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + 'path', nargs='+', + help='path to load') + + args = parser.parse_args() + + for path in args.path: + if ':' in path: + path,trace = path.split(':') + curve = Curve(path=path, trace=int(trace)) + print(curve.dumps()) + curve.plot() + else: + for curve in load_all_traces(path): + print(curve.dumps()) + curve.plot() + _pyplot.show()