diff --git a/FrgTools/frgtools/Untitled2.ipynb b/FrgTools/frgtools/Untitled2.ipynb new file mode 100644 index 0000000..c0d7e6d --- /dev/null +++ b/FrgTools/frgtools/Untitled2.ipynb @@ -0,0 +1,212 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [], + "source": [ + "# getCV\n", + "\"\"\"\n", + "Loads CV data from a text file. Pulls the last curve out of the\n", + "repeats (red/ox cycle).\n", + "Returns structure. \n", + "\n", + "Example: mydata = getCV (use UI to select file)\n", + "\n", + " mydata = getCV ('C:\\Myname\\CV\\File.ras') (directly offer filepath)\n", + "\n", + "Onset potential methods: \n", + " 1: Direct voltage at minimum cathodic peak\n", + " 2: Inflection point\n", + " 3: Intersection at baseline\n", + " 4: Fixed\n", + "\"\"\"\n", + "import os\n", + "import csv\n", + "import numpy as np\n", + "\n", + "# def getFileList(directory = os.path.dirname(file_name)):#os.path.realpath(__file__)))\n", + "# return os.listdir(directory)\n", + "# getFileList(filepath)\n", + "\n", + "def getCV(fpath, area =1):\n", + " cvdata = getcvdata(fpath)\n", + " cvdata = getOnsetPotentials(cvdata)\n", + " return cvdata\n", + "\n", + "def getcvdata(filepath, area = 1, nheaderlines = 53):\n", + " area = float(area)\n", + " rawCV = {'voltage' : [],\n", + " 'current' : [],\n", + " 'cycle' : [] }\n", + "\n", + " with open(filepath,'r') as f:\n", + " [next(f) for item in range(nheaderlines)] # Skips until the 54th line, where header line is. \n", + " f_reader = csv.DictReader(f, delimiter = '\\t') \n", + " for row in f_reader:\n", + " rawCV['voltage'].append(row['Ewe/V'])\n", + " rawCV['current'].append(row['/mA'])\n", + " rawCV['cycle'].append(row['cycle number'])\n", + "\n", + " num_of_scans = np.unique(rawCV['cycle'])\n", + " fs = num_of_scans[-1]\n", + " final_scan = {'voltage' : [],\n", + " 'current' : [],\n", + " 'currentdensity' : np.array([])}\n", + "\n", + " j = 0 # This can probably be optimized. Final scan is the only important one.\n", + " for n in rawCV['cycle']:\n", + " if n == fs:\n", + " final_scan['voltage'].append(rawCV['voltage'][j])\n", + " final_scan['current'].append(rawCV['current'][j])\n", + " j += 1\n", + " \n", + " final_scan['voltage'] = np.array(final_scan['voltage'], dtype = float)\n", + " final_scan['current'] = np.array(final_scan['current'], dtype = float)\n", + " final_scan['currentdensity'] = np.divide(final_scan['current'], area) # Gets current density\n", + " return final_scan\n", + "\n", + "def smooth(a,WSZ=5):\n", + " # a: NumPy 1-D array containing the data to be smoothed\n", + " # WSZ: smoothing window size needs, which must be odd number,\n", + " # as in the original MATLAB implementation\n", + " out0 = np.convolve(a,np.ones(WSZ,dtype=int),'valid')/WSZ \n", + " r = np.arange(1,WSZ-1,2)\n", + " start = np.cumsum(a[:WSZ-1])[::2]/r\n", + " stop = (np.cumsum(a[:-WSZ:-1])[::2]/r)[::-1]\n", + " return np.concatenate(( start , out0, stop ))\n", + "\n", + "def getOnsetPotentials(cvdata,fitwidth = 40):\n", + " #cvdata should be dict, output from getCV\n", + " \n", + " # Finding cathodic peak voltage\n", + " X = cvdata['voltage']\n", + " Y = cvdata['currentdensity']\n", + " idx0 = np.argmin(Y)\n", + " cvdata['cathodic_peak'] = X[idx0] \n", + " \n", + " # Finding anodic peak current at the end of the voltammogram\n", + " idx1 = np.argmax(X)\n", + " cvdata['anodic_peak'] = Y[idx1] \n", + "\n", + " # Inflection point onset\n", + " idx2 = np.argmin(X)\n", + " XX = X[idx1+500 : idx2 - 20]\n", + " YY = Y[idx1+500 : idx2 - 20]\n", + " \n", + " dydx = np.gradient(YY)/np.gradient(XX) # Finds first derivative, delta y/ delta x\n", + " dydx = smooth(dydx)\n", + " \n", + " idx3 = np.argmax(dydx) # Inflection point on the cathodic curve\n", + " idx4 = np.argmin(abs(YY)) # Getting closest to the baseline center as possible\n", + " cvdata['inflection_onset'] = XX[idx3]\n", + " \n", + " X_ = XX[idx3 - fitwidth//2: idx3 + fitwidth//2]\n", + " Y_ = YY[idx3 - fitwidth//2: idx3 + fitwidth//2]\n", + " linfit_3 = np.polyfit(X_,Y_,1)\n", + " \n", + " X_ = XX[idx4 - fitwidth//2: idx4 + fitwidth//2]\n", + " Y_ = YY[idx4 - fitwidth//2: idx4 + fitwidth//2]\n", + " linfit_4 = np.polyfit(X_,Y_,1)\n", + " \n", + " intersect_x = (linfit_4[1] - linfit_3[1]) / (linfit_3[0] - linfit_4[1])\n", + " intersect_y = linfit_3[0] * intersect_x + linfit_3[1]\n", + " cvdata['intersect_onset'] = [intersect_x, intersect_y]\n", + " return cvdata\n" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'voltage': array([0.19229576, 0.19345422, 0.19439143, ..., 0.19039437, 0.19128586,\n", + " 0.19239724]), 'current': array([0.00034713, 0.00034614, 0.00034744, ..., 0.00037424, 0.00037562,\n", + " 0.00040446]), 'currentdensity': array([0.00069426, 0.00069228, 0.00069488, ..., 0.00074847, 0.00075123,\n", + " 0.00080892])}\n" + ] + } + ], + "source": [ + "cvdata = getcvdata(filepath, area = .5)\n", + "print(cvdata)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'voltage': array([0.19229576, 0.19345422, 0.19439143, ..., 0.19039437, 0.19128586,\n", + " 0.19239724]),\n", + " 'current': array([0.00034713, 0.00034614, 0.00034744, ..., 0.00037424, 0.00037562,\n", + " 0.00040446]),\n", + " 'currentdensity': array([0.00034713, 0.00034614, 0.00034744, ..., 0.00037424, 0.00037562,\n", + " 0.00040446]),\n", + " 'cathodic_peak': -0.444778711,\n", + " 'anodic_peak': 0.010884792647427984,\n", + " 'inflection_onset': -0.309950382,\n", + " 'intersect_onset': [-0.18963104576730827, -0.00028764459757954497]}" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "filepath = r\"C:\\Users\\Skaggs\\Desktop\\Perovskites\\2019_08_09 CV SnOx\\10nm\\180_11.4_FTO_02_CV_C02.txt\"\n", + "getCV(filepath)" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "4199" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(_['voltage'])" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/FrgTools/frgtools/cyclicvolt.py b/FrgTools/frgtools/cyclicvolt.py new file mode 100644 index 0000000..9cbc3a2 --- /dev/null +++ b/FrgTools/frgtools/cyclicvolt.py @@ -0,0 +1,28 @@ +# getCV +""" +Loads CV data from a text file. Pulls the last curve out of the +repeats (red/ox cycle). +Returns structure. + +Example: mydata = getCV (use UI to select file) + + mydata = getCV ('C:\Myname\CV\File.ras') (directly offer filepath) + +Onset potential methods: + 1: Direct minimum + 2: Inflection point + 3: Intersection at baseline + 4: Fixed +""" +import os + +def getFileList(directory = os.path.dirname(file_name)):#os.path.realpath(__file__))) + return os.listdir(directory) + +def getCV(filepath, area=1): + #getFileList(filepath) + txt = open(filepath,'r') + if area == 1: + #Make title say Current (mA) + +print(getCV("C:\Users\Skaggs\Desktop\Perovskites\2019_08_09 CV SnOx\10nm\180_11.4_FTO_02_CV_C02")) \ No newline at end of file