added data prep
This commit is contained in:
parent
da49bf68d6
commit
f8782fb258
@ -30,6 +30,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
from .keithley import keithley as _keithley
|
from .keithley import keithley as _keithley
|
||||||
from .utility import data as _data
|
from .utility import data as _data
|
||||||
|
from .utility.data import load_dataframe
|
||||||
from .utility import file_io
|
from .utility import file_io
|
||||||
from .utility import testing
|
from .utility import testing
|
||||||
|
|
||||||
@ -155,6 +156,15 @@ def measure(max_measurements=None):
|
|||||||
You can take the data from the buffer afterwards, using save_csv """
|
You can take the data from the buffer afterwards, using save_csv """
|
||||||
_measure(max_measurements=max_measurements, monitor=False)
|
_measure(max_measurements=max_measurements, monitor=False)
|
||||||
|
|
||||||
|
def automeasure(repeat, repeat_delay=0, max_measurements=None, max_points_shown=120, monitor=True):
|
||||||
|
"""
|
||||||
|
Measure and save to csv multiple times
|
||||||
|
"""
|
||||||
|
for i in range(repeat):
|
||||||
|
_measure(max_measurements=max_measurements, max_points_shown=max_points_shown, monitor=monitor)
|
||||||
|
save_csv()
|
||||||
|
sleep(repeat_delay)
|
||||||
|
|
||||||
|
|
||||||
def get_dataframe():
|
def get_dataframe():
|
||||||
"""
|
"""
|
||||||
@ -199,20 +209,6 @@ def save_pickle():
|
|||||||
df.to_pickle(filename)
|
df.to_pickle(filename)
|
||||||
print(f"Saved as '{filename}'")
|
print(f"Saved as '{filename}'")
|
||||||
|
|
||||||
def load_dataframe(p:str):
|
|
||||||
"""
|
|
||||||
Load a dataframe from file.
|
|
||||||
@param p : path of the file. If it has 'csv' extension, pandas.read_csv is used, pandas.read_pickle otherwise
|
|
||||||
"""
|
|
||||||
if not path.isfile(p):
|
|
||||||
print(f"ERROR: load_dataframe: File does not exist: {p}")
|
|
||||||
return None
|
|
||||||
if p.endswith(".csv"):
|
|
||||||
df = pd.read_csv(p)
|
|
||||||
else:
|
|
||||||
df = pd.read_pickle(p)
|
|
||||||
return df
|
|
||||||
|
|
||||||
def run_script(script_path):
|
def run_script(script_path):
|
||||||
"""
|
"""
|
||||||
Run a lua script on the Keithley device
|
Run a lua script on the Keithley device
|
||||||
@ -253,6 +249,7 @@ def help(topic=None):
|
|||||||
Functions:
|
Functions:
|
||||||
measure - measure the voltage
|
measure - measure the voltage
|
||||||
monitor - measure the voltage with live monitoring in a matplotlib window
|
monitor - measure the voltage with live monitoring in a matplotlib window
|
||||||
|
automeasure - measure and save to csv multiple times
|
||||||
get_dataframe - return smua.nvbuffer1 as pandas dataframe
|
get_dataframe - return smua.nvbuffer1 as pandas dataframe
|
||||||
save_csv - save the last measurement as csv file
|
save_csv - save the last measurement as csv file
|
||||||
save_pickle - save the last measurement as pickled pandas dataframe
|
save_pickle - save the last measurement as pickled pandas dataframe
|
@ -14,7 +14,6 @@ for key,val in scripts.items():
|
|||||||
scripts[key] = script_dir + scripts[key]
|
scripts[key] = script_dir + scripts[key]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def init_keithley(beep_success=True):
|
def init_keithley(beep_success=True):
|
||||||
rm = pyvisa.ResourceManager('@py')
|
rm = pyvisa.ResourceManager('@py')
|
||||||
resources = rm.list_resources()
|
resources = rm.list_resources()
|
||||||
|
4
k-teng/materials
Normal file
4
k-teng/materials
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pdms
|
||||||
|
kapton
|
||||||
|
plastic
|
||||||
|
|
151
k-teng/prepare.py
Normal file
151
k-teng/prepare.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
import scipy.signal as signal
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from time import sleep
|
||||||
|
from random import choice as r_choice
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if __package__ is None:
|
||||||
|
# make relative imports work as described here: https://peps.python.org/pep-0366/#proposed-change
|
||||||
|
__package__ = "k-teng"
|
||||||
|
import sys
|
||||||
|
from os import path
|
||||||
|
filepath = path.realpath(path.abspath(__file__))
|
||||||
|
sys.path.insert(0, path.dirname(path.dirname(filepath)))
|
||||||
|
from .utility.data import load_dataframe
|
||||||
|
|
||||||
|
file = "/home/matth/data/gel_big_gap000.csv"
|
||||||
|
|
||||||
|
class PeakInfo:
|
||||||
|
"""
|
||||||
|
Helper class for "iterating" through selected peaks.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._peak_names = [ "first", "second", "last", "lowest" ]
|
||||||
|
self._peaks = { p: None for p in self._peak_names }
|
||||||
|
self._iter = 0
|
||||||
|
|
||||||
|
def current(self):
|
||||||
|
# return (self._peak_names[self._iter]), self._peaks[self._peak_names[self._iter]]
|
||||||
|
return self._peaks[self._peak_names[self._iter]]
|
||||||
|
def name(self):
|
||||||
|
return self._peak_names[self._iter]
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
if self._iter < len(self._peak_names) - 1: self._iter += 1
|
||||||
|
return self.current()
|
||||||
|
def prev(self):
|
||||||
|
if self._iter > 0: self._iter -= 1
|
||||||
|
return self.current()
|
||||||
|
|
||||||
|
def set(self, value):
|
||||||
|
"""Assign a value to the crrent peak"""
|
||||||
|
self._peaks[self._peak_names[self._iter]] = value
|
||||||
|
def is_done(self):
|
||||||
|
for peak in self._peaks.values():
|
||||||
|
if peak is None: return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self._peaks[key]
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self._peaks[key] = value
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self._peak_names[self._iter]} peak"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def find_peaks(a):
|
||||||
|
peaks = signal.find_peaks(a)
|
||||||
|
|
||||||
|
|
||||||
|
def on_click(fig, ax, peaks, event):
|
||||||
|
"""
|
||||||
|
Let the user select first, second and last peak by clicking on them in this order.
|
||||||
|
Right click undos the last selection
|
||||||
|
"""
|
||||||
|
select = None
|
||||||
|
if event.button == 1: # left click
|
||||||
|
peaks.set((event.xdata, event.ydata))
|
||||||
|
print(f"{peaks}: {event.xdata} - {event.ydata}")
|
||||||
|
ax.set_title(f"{peaks}: {event.xdata} - {event.ydata}")
|
||||||
|
peaks.next()
|
||||||
|
elif event.button == 3: # right click
|
||||||
|
ax.set_title(f"Undo {peaks.name()}")
|
||||||
|
if not peaks.is_done():
|
||||||
|
peaks.prev()
|
||||||
|
peaks.set(None)
|
||||||
|
if peaks.is_done(): message = "Close window when done"
|
||||||
|
else: message = f"Click on {peaks}"
|
||||||
|
fig.suptitle(message)
|
||||||
|
fig.canvas.draw()
|
||||||
|
# fig1.canvas.flush_events()
|
||||||
|
|
||||||
|
def calc_peaks(peaks):
|
||||||
|
# get the peak points from the information of a Peaks object
|
||||||
|
# 90% distance between first and second
|
||||||
|
min_distance = max(1, (peaks["second"][0] - peaks["first"][0]) * 0.9)
|
||||||
|
min_height = peaks["lowest"][1] * 0.99
|
||||||
|
vpeaks = signal.find_peaks(vdata, height=min_height, distance=min_distance)
|
||||||
|
return vpeaks
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(a):
|
||||||
|
"""
|
||||||
|
normalize so that all values are between 0 and 1
|
||||||
|
"""
|
||||||
|
min_ = np.min(a)
|
||||||
|
a = a - min_
|
||||||
|
max_ = np.max(a)
|
||||||
|
if max_ != 0:
|
||||||
|
a = a / max_
|
||||||
|
return a
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
"""
|
||||||
|
Peak identification:
|
||||||
|
plot, let user choose first, second, last and lowest peak for identification
|
||||||
|
"""
|
||||||
|
df = load_dataframe(file)
|
||||||
|
a = df.to_numpy()
|
||||||
|
vdata = normalize(a[:,2])
|
||||||
|
plt.ion()
|
||||||
|
# vpeaks[0] is the list of the peaks
|
||||||
|
vpeaks = signal.find_peaks(vdata)[0]
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
ax.plot(vdata)
|
||||||
|
peak_lines = ax.vlines(vpeaks, 0, 1, colors="r")
|
||||||
|
ax.grid(True)
|
||||||
|
fig.suptitle("Click on first peak")
|
||||||
|
peak_info = PeakInfo()
|
||||||
|
# handle clicks
|
||||||
|
fig.canvas.mpl_connect("button_press_event", lambda ev: on_click(fig, ax, peak_info, ev))
|
||||||
|
# run until user closes, events are handled with on_click function
|
||||||
|
print(vdata.size)
|
||||||
|
while plt.fignum_exists(fig.number):
|
||||||
|
plt.pause(0.01)
|
||||||
|
if (peak_info.is_done()):
|
||||||
|
vpeaks = calc_peaks(peak_info)[0]
|
||||||
|
x_margin = (a[-1,0] - a[0,0]) * 0.05 # allow some margin if user clicked not close enough on peak
|
||||||
|
vpeaks = vpeaks[(vpeaks >= peak_info["first"][0] - x_margin) & (vpeaks <= peak_info["last"][0] + x_margin)] # remove peaks before first and after last
|
||||||
|
peak_lines.remove()
|
||||||
|
peak_lines = ax.vlines(vpeaks, 0, 1, colors="r")
|
||||||
|
peak_info.reset()
|
||||||
|
print(a[:,0], vpeaks)
|
||||||
|
|
||||||
|
# separate peaks
|
||||||
|
indices = np.arange(0, a[:,0].size)
|
||||||
|
peak_datas = []
|
||||||
|
for i in range(len(vpeaks) - 1):
|
||||||
|
# TODO: user <= or <
|
||||||
|
peak_datas.append(vdata[(indices >= vpeaks[i]) & (indices < vpeaks[i+1])])
|
||||||
|
plt.plot(peak_datas[i])
|
||||||
|
print(peak_datas)
|
||||||
|
plt.pause(20)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from os import path
|
||||||
|
|
||||||
def buffer2dataframe(buffer):
|
def buffer2dataframe(buffer):
|
||||||
df = pd.DataFrame(buffer)
|
df = pd.DataFrame(buffer)
|
||||||
@ -15,3 +16,17 @@ def buffers2dataframe(ibuffer, vbuffer):
|
|||||||
df = pd.DataFrame(np.vstack((ibuffer[:,0], ibuffer[:,1], vbuffer[:,1])).T)
|
df = pd.DataFrame(np.vstack((ibuffer[:,0], ibuffer[:,1], vbuffer[:,1])).T)
|
||||||
df.columns = ["Time [s]", "Current [A]", "Voltage [V]"]
|
df.columns = ["Time [s]", "Current [A]", "Voltage [V]"]
|
||||||
return df
|
return df
|
||||||
|
|
||||||
|
def load_dataframe(p:str):
|
||||||
|
"""
|
||||||
|
Load a dataframe from file.
|
||||||
|
@param p : path of the file. If it has 'csv' extension, pandas.read_csv is used, pandas.read_pickle otherwise
|
||||||
|
"""
|
||||||
|
if not path.isfile(p):
|
||||||
|
print(f"ERROR: load_dataframe: File does not exist: {p}")
|
||||||
|
return None
|
||||||
|
if p.endswith(".csv"):
|
||||||
|
df = pd.read_csv(p)
|
||||||
|
else:
|
||||||
|
df = pd.read_pickle(p)
|
||||||
|
return df
|
||||||
|
Loading…
Reference in New Issue
Block a user