def test_filelist(self):
		test_oect = oect.OECT(folder='tests/test_device/01')
		test_oect.filelist()
		assert (os.path.join('tests/test_device/01', 'uc1_kpf6_output_0.txt') in test_oect.files
			and os.path.join('tests/test_device/01', 'uc1_kpf6_output_1.txt') in test_oect.files
			and os.path.join('tests/test_device/01', 'uc1_kpf6_transfer_0.txt') in test_oect.files
			and test_oect.config[0] == os.path.join('tests/test_device/01', 'uc1_kpf6_config.cfg'))
	def test_get_metadata(self):
		test_oect = oect.OECT(folder=os.getcwd())
		test_file = 'tests/test_device/metadata_test/uc1_kpf6_output_0.txt'
		test_oect.get_metadata(test_file)
		assert (test_oect.Vg == -.5
			and test_oect.W == 2000
			and test_oect.L == 20)
	def test_get_metadata_no_config(self):
		test_oect = oect.OECT(folder='tests/test_device/metadata_test')
		test_oect.make_config = True
		test_file = 'tests/test_device/metadata_test/uc1_kpf6_output_0.txt'
		test_oect.get_metadata(test_file)
		assert (test_oect.Vg == -.5
			and test_oect.W == 4000
			and test_oect.L == 10)
	def test_filelist_noconfig(self):
		test_oect = oect.OECT(folder='tests/test_device/no_config')
		config_check = 'config.cfg' in os.listdir('tests/test_device/no_config')
		try:
			os.remove('tests/test_device/no_config/config.cfg')
		except:
			pass
		assert config_check
	def test_set_params_defaults(self):
		test_oect = oect.OECT(folder=os.getcwd())
		test_oect.set_params({}, {}, {}, {}) #try defaults
		assert (test_oect.options['gm_method'] == 'sg' 
			and test_oect.options['Reverse'] == True
			and test_oect.options['Average'] == False
			and test_oect.options['V_low'] == False
			and test_oect.options['overwrite'] == False)
def loadOECT(path,
             dimDict,
             params=None,
             gm_plot=True,
             plot=True,
             options={},
             verbose=True,
             text_browser=None):
    """
	Wrapper function for processing OECT data

	params = {W: , L: , d: } for W, L, d of device

	USAGE:
		device1 = loadOECT(folder_name)
	"""

    if not path:
        path = file_open(caption='Select device subfolder')

    device = oect.OECT(path, dimDict, params, options)
    device.calc_gms()
    device.thresh()

    scaling = device.WdL  # W *d / L

    if verbose:
        for key in device.gms:
            print(
                key, ': {:.2f}'.format(
                    np.max(device.gms[key].values * 1e-2) / scaling),
                'S/cm scaled')
            print(key,
                  ': {:.2f}'.format(np.max(device.gms[key].values * 1000)),
                  'mS max')
            if (text_browser):
                text_browser.append(key + str(': {:.2f}'.format(
                    np.max(device.gms[key].values * 1e-2) / scaling)) +
                                    'S/cm scaled')
                text_browser.append(key + str(': {:.2f}'.format(
                    np.max(device.gms[key].values * 1000))) + 'mS max')

    if plot:
        fig = oect_plot.plot_transfers_gm(device,
                                          gm_plot=gm_plot,
                                          leakage=True)
        fig.savefig(path + r'\transfer_leakage.tif', format='tiff')
        fig = oect_plot.plot_transfers_gm(device,
                                          gm_plot=gm_plot,
                                          leakage=False)
        fig.savefig(path + r'\transfer.tif', format='tiff')
        fig = oect_plot.plot_outputs(device, leakage=True)
        fig.savefig(path + r'\output_leakage.tif', format='tiff')
        fig = oect_plot.plot_outputs(device, leakage=False)
        fig.savefig(path + r'\output.tif', format='tiff')
    return device
	def test_set_params(self):
		test_oect = oect.OECT(folder='tests/test_device/01') #called in init
		assert (test_oect.params['W'] == 4000.0
			and test_oect.params['L'] == 20.0
			and test_oect.params['d'] == 4e-8
			and test_oect.params['Preread (ms)'] == 20000
			and test_oect.params['First Bias (ms)'] == 120000
			and test_oect.params['Vds (V)'] == 0
			and test_oect.params['output_Preread (ms)'] == 5000
			and test_oect.params['output_First Bias (ms)'] == 200
			and test_oect.params['Output Vgs'] == 2
			and test_oect.params['Vgs'] == [-0.5, -0.8])
	def test_update_config(self):
		test_oect = oect.OECT(folder='tests/test_device/no_config')
		#config will be auto generated in init
		#default config will be made with values:
		# [Dimensions]
		# Width (um) = 2000
		# Length (um) = 20

		# [Transfer]
		# Preread (ms) = 30000.0
		# First Bias (ms) = 120000.0
		# Vds (V) = -0.6

		# [Output]
		# Preread (ms) = 500.0
		# First Bias (ms) = 200.0
		# Output Vgs = 4
		# Vgs (V) 0 = -0.1
		# Vgs (V) 1 = -0.3
		# Vgs (V) 2 = -0.5
		# Vgs (V) 3 = -0.9
		test_oect.W = 4000
		test_oect.L = 10
		test_oect.Vd = -1
		test_oect.Vg_array = [0, .1, .2, .3, .4]
		test_oect.update_config()
		config = configparser.ConfigParser()
		config.read(test_oect.config)
		assert (config['Dimensions']['Width (um)'] == '4000'
			and config['Dimensions']['Length (um)'] == '10'
			and config['Transfer']['Vds (V)'] == '-1'
			and config['Output']['Preread (ms)'] == '500.0'
			and config['Output']['First Bias (ms)'] == '200.0'
			and config['Output']['Vgs (V) 0'] == '0'
			and config['Output']['Vgs (V) 1'] == '0.1'
			and config['Output']['Vgs (V) 2'] == '0.2'
			and config['Output']['Vgs (V) 3'] == '0.3'
			and config['Output']['Vgs (V) 4'] == '0.4')
		try:
			os.remove('tests/test_device/no_config/config.cfg')
		except:
			pass
	def test_reverse_with_sweep(self):
		test_oect = oect.OECT(folder=os.getcwd())
		a = np.arange(start=-1, stop=1.1, step=.1)
		b = np.arange(start=.9, stop=-1.1, step=-.1)
		v = np.concatenate((a, b))
		assert len(v) // 2, True == test_oect._reverse(v)
Exemple #10
0
import os
import sys
import pytest
import configparser
import numpy as np
sys.path.insert(0, '..')

import oect
test_oect = oect.OECT(folder='test_device/no_config')
print(os.path.isfile(os.path.join('test_device/no_config', 'config.cfg')))
Exemple #11
0
	def test_output_curve_wrong_col_names(self):
		test_oect = oect.OECT(folder=os.getcwd())
		with pytest.raises(KeyError):
			test_file = 'tests/test_device/01/uc1_kpf6_output_0.txt'
			test_oect.get_metadata(test_file)
			test_oect.transfer_curve(test_file)
Exemple #12
0
	def test_set_params_not_dict(self):
		test_oect = oect.OECT(folder=os.getcwd())
		with pytest.raises(IndexError) or pytest.raises(TypeError):
			test_oect.set_params([1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
Exemple #13
0
	def test_all_outputs(self):
		test_oect = oect.OECT(folder='tests/test_device/01') #called in init
		assert test_oect.num_outputs == 4
Exemple #14
0
	def test_set_params_add(self):
		test_oect = oect.OECT(folder='tests/test_device/01', params={'test_param1': 100},
			options={'test_option1': 200})
		assert (test_oect.params['test_param1'] == 100
			and test_oect.options['test_option1'] == 200)
Exemple #15
0
	def test_set_opts(self):
		test_oect = oect.OECT(folder='tests/test_device/options_test') #called in init
		assert (test_oect.options['Reverse'] == True
			and test_oect.options['Average'] == False
			and test_oect.options['gm_method'] == 'method'
			and test_oect.options['V_low'] == 10)
Exemple #16
0
def average(dimDict={},
            path='',
            thickness=40e-9,
            plot=True,
            text_browser=None):
    '''
	averages data in this particular path (for folders 'avg')

	path: str
		string path to folder '.../avg'. Note Windows path are of form r'Path_name'

	thickness : float
		approximate film thickness. Standard polymers (for Raj) are ~40 nm

	plot : bool
		Whether to plot or not. Not plotting is very fast!


	Returns
	-------
	pixels : dict of OECT
		Contains the various OECT class devices

	Id_Vg : pandas dataframe
		Contains the averaged Id vs Vg (drain current vs gate voltage, transfer)

	Id_Vd : pandas dataframe
		Contains the averaged Id vs Vg (drain current vs drain voltages, output)

	'''

    if not path:
        path = file_open(caption='Select avg subfolder')
        print('Loading from', path)

    filelist = os.listdir(path)

    # removes all but the folders in pixel_names
    f = filelist[:]
    for k in filelist:
        try:
            sub_num = int(k)
        except:
            print('Ignoring', k)
            f.remove(k)
    filelist = f[:]
    del f

    paths = [os.path.join(path, name) for name in filelist]

    # removes random files instead of the sub-folders
    for p in paths:
        if not os.path.isdir(p):
            paths.remove(p)

    pixels = {}
    # loads all the folders
    for p, f in zip(paths, filelist):
        dv = loadOECT(dimDict,
                      p,
                      params={'d': thickness},
                      gm_plot=plot,
                      plot=plot,
                      text_browser=text_browser)
        pixels[f] = dv

    # average Id-Vg
    Id_Vg = []
    first_pxl = pixels[list(pixels.keys())[0]]

    for dv in pixels:

        if not any(Id_Vg):

            Id_Vg = pixels[dv].transfers.values

        else:

            Id_Vg += pixels[dv].transfers.values

    Id_Vg /= len(pixels)
    Id_Vg = pd.DataFrame(data=Id_Vg)

    try:
        Id_Vg = Id_Vg.set_index(first_pxl.transfers.index)
    except:
        Id_Vg = Id_Vg.set_index(pixels[list(pixels.keys())[-1]])

    # find gm of the average
    temp_dv = oect.OECT(dimDict, paths[0], {'d': thickness})
    _gm_fwd, _gm_bwd = temp_dv._calc_gm(Id_Vg)
    Id_Vg['gm_fwd'] = _gm_fwd
    if not _gm_bwd.empty:
        Id_Vg['gm_bwd'] = _gm_bwd

    Id_Vg = Id_Vg.rename(columns={0: 'Id average'})  # fix a naming bug

    if temp_dv.reverse:
        Id_Vg.reverse = True
        Id_Vg.rev_point = temp_dv.rev_point

    # average Id-Vd at max Vd
    Id_Vd = []

    # finds column corresponding to lowest voltage (most doping), but these are strings
    idx = np.argmin(np.array([float(i) for i in first_pxl.outputs.columns]))
    volt = first_pxl.outputs.columns[idx]

    for dv in pixels:

        if not any(Id_Vd):

            Id_Vd = pixels[dv].outputs[volt].values

        else:

            Id_Vd += pixels[dv].outputs[volt].values

    Id_Vd /= len(pixels)
    Id_Vd = pd.DataFrame(data=Id_Vd)

    try:
        Id_Vd = Id_Vd.set_index(pixels[list(
            pixels.keys())[0]].outputs[volt].index)
    except:
        Id_Vd = Id_Vd.set_index(pixels[list(
            pixels.keys())[-1]].outputs[volt].index)

    if plot:
        fig = oect_plot.plot_transfer_avg(Id_Vg, temp_dv.WdL)
        fig.savefig(path + r'\transfer_avg.tif', format='tiff')
        fig = oect_plot.plot_output_avg(Id_Vd)
        fig.savefig(path + r'\output_avg.tif', format='tiff')
    return pixels, Id_Vg, Id_Vd, temp_dv.WdL
Exemple #17
0
	def test_reverse_no_sweep(self):
		test_oect = oect.OECT(folder=os.getcwd())
		v = np.arange(start=-1, stop=.1, step=.1)
		assert len(v) // 2, False  == test_oect._reverse(v)
Exemple #18
0
	def test_all_transfers(self):
		test_oect = oect.OECT(folder='tests/test_device/01') #called in init
		assert test_oect.num_transfers == 2
Exemple #19
0
	def test_all_outputs_append(self):
		test_oect = oect.OECT(folder='tests/test_device/01') #called in init
		test_oect.all_outputs() #call again
		assert test_oect.num_outputs == 8