Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 632dfc5278 | |||
| 6f80ecc7d1 | |||
| 53e3bd27ef | |||
| 7715c806b8 | |||
| 17f5ece9c4 | |||
| fa4b563470 |
@@ -1,4 +1,4 @@
|
||||
# FTIR-IV
|
||||
Script for IV measurements of samples in FTIR cryostat at PSI
|
||||
Script for IV measurements using Keithley 196 DMM for voltage measurements, and the SIM900 rack with the SIM928 voltage source. Use `iv_run.py` to run the IV measurement.
|
||||
|
||||
To use, run `SIM900-SIM928-Keithly196-IV.py`
|
||||
Note that the script is made specifically for these instruments. The command messages need to be changed if you would like to use it with other instruments. Command messages are found in the manuals of the corresponding instruments.
|
||||
|
||||
@@ -13,9 +13,9 @@ from pathlib import Path
|
||||
import tomllib
|
||||
rm = pyvisa.ResourceManager()
|
||||
|
||||
import SIM900_commands as SIM900_comm
|
||||
import SIM928_commands as SIM928_comm
|
||||
import Keithley196_commands as Keithley_comm
|
||||
from command_functions import SIM900_commands as SIM900_comm
|
||||
from command_functions import SIM928_commands as SIM928_comm
|
||||
from command_functions import Keithley196_commands as Keithley_comm
|
||||
|
||||
with open("automated-iv-curves/config.toml", "rb") as f:
|
||||
cfg = tomllib.load(f)
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Wed Oct 05 14:27:45 2022
|
||||
|
||||
@author: Jamie
|
||||
"""
|
||||
# Function for controlling Keithly-196 for electrical measurements
|
||||
|
||||
# Function to output voltage in Volts
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
def Voltage(Keithley):
|
||||
Keithley.write("X\n")
|
||||
Voltage_string = Keithley.read()
|
||||
Voltage = float(Voltage_string[4:])
|
||||
return Voltage
|
||||
|
||||
# Function to set measurement mode
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
# mode is the measurement mode
|
||||
def Set_Mode(Keithley, mode):
|
||||
if mode == "DC V":
|
||||
mode_number = 0
|
||||
elif mode == "AC V":
|
||||
mode_number = 1
|
||||
elif mode == "Ohm":
|
||||
mode_number = 2
|
||||
elif mode == "DC I":
|
||||
mode_number = 3
|
||||
elif mode == "DC I":
|
||||
mode_number = 4
|
||||
elif mode == "AC I":
|
||||
mode_number = 5
|
||||
elif mode == "ACV dB":
|
||||
mode_number = 6
|
||||
elif mode == "Offset comp Ohm":
|
||||
mode_number = 7
|
||||
Keithley.write("F"+str(mode_number))
|
||||
|
||||
# Function to set voltage range
|
||||
# Keithley is the VISA resource for the Keithley-196
|
||||
# range_name is the number of the range setting (numbers in V)
|
||||
def Set_Range(Keithley, range_name):
|
||||
if range_name == "Auto":
|
||||
range_number = 0
|
||||
elif range_name == "0.3":
|
||||
range_number = 1
|
||||
elif range_name == "3":
|
||||
range_number = 2
|
||||
elif range_name == "30":
|
||||
range_number = 3
|
||||
elif range_name == "300":
|
||||
range_number = 4
|
||||
Keithley.write("R"+str(range_number)+"X")
|
||||
@@ -1,230 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 16:05:44 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Program to do I-V measurements
|
||||
# Using SIM928 voltage source within SIM900 mainframe
|
||||
# Using Keithley196 for voltage measurement
|
||||
|
||||
import time
|
||||
import datetime
|
||||
import os.path
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import pyvisa
|
||||
from pathlib import Path
|
||||
rm = pyvisa.ResourceManager()
|
||||
|
||||
import SIM900_commands as SIM900_comm
|
||||
import SIM928_commands as SIM928_comm
|
||||
import Keithley196_commands as Keithley_comm
|
||||
|
||||
Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'
|
||||
# Keithley_address = 'GPIB0::6::INSTR'
|
||||
SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'
|
||||
|
||||
Keithley = rm.open_resource(Keithley_address)
|
||||
SIM900 = rm.open_resource(SIM900_address)
|
||||
SIM928_port = 1
|
||||
|
||||
# Initialise Keithley
|
||||
Keithley.clear()
|
||||
Keithley.timeout = 5000
|
||||
Keithley.read_termination = '\n'
|
||||
Keithley.write("T5X\n") # Ensures the Keithley reads when it is triggered by "X" write
|
||||
Keithley_comm.Set_Mode(Keithley, "DC V")
|
||||
Keithley_comm.Set_Range(Keithley, "Auto")
|
||||
Keithley.read() # Throwaway
|
||||
|
||||
# Initialise SIM900
|
||||
SIM900_comm.flush_main(SIM900)
|
||||
SIM900_comm.reset(SIM900)
|
||||
SIM900_comm.flush_port(SIM900, SIM928_port)
|
||||
|
||||
# Function to read the voltage set by a voltage source
|
||||
def read_source_V():
|
||||
count = 0
|
||||
voltage = SIM900_comm.send_query(SIM900, SIM928_port, SIM928_comm.read_voltage(), 128) # get voltage
|
||||
print("returned data: "+voltage)
|
||||
while (count<10) and (type(voltage)!= float):
|
||||
try:
|
||||
voltage = float(voltage)
|
||||
except:
|
||||
print('no float')
|
||||
voltage = SIM900_comm.send_query(SIM900, SIM928_port, SIM928_comm.read_voltage(), 128) # get voltage
|
||||
print("returned data: "+voltage)
|
||||
count = count + 1
|
||||
return voltage
|
||||
|
||||
#print(read_source_V())
|
||||
|
||||
# Function to set voltage of SIM928
|
||||
def set_voltage(V_value=1e-3):
|
||||
if V_value > 20:
|
||||
print ('Voltage setting too high (>10V), it is set to 10V')
|
||||
V_value = 20
|
||||
elif V_value < -20:
|
||||
print ('Voltage setting too high (<-10V), it is set to -10V')
|
||||
V_value = -20
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage
|
||||
time.sleep(1)
|
||||
# count = 0
|
||||
# while (count<10) and (read_source_V()!= V_value):
|
||||
# print('Setting voltage again')
|
||||
# time.sleep(1) #wait 1 second
|
||||
# SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage
|
||||
# count = count + 1
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("on"))
|
||||
print('Voltage set to ' + str(V_value))
|
||||
# return read_source_V()
|
||||
|
||||
# Function to measure the current from the Keithley voltmeter
|
||||
# time_average is the averaging time, time_interval is the time between points
|
||||
# Could also use "Filter (P)" command to set the Keithley's internal averaging time
|
||||
def measure_V(time_average=10, time_interval=0.2):
|
||||
N_points = time_average/time_interval + 1
|
||||
V_list = []
|
||||
i = 1
|
||||
Keithley_comm.Set_Range(Keithley, "Auto") #set auto range
|
||||
time.sleep(time_interval)
|
||||
while i < N_points:
|
||||
V_list.append(Keithley_comm.Voltage(Keithley)) #read the voltage
|
||||
time.sleep(time_interval)
|
||||
i = i+1
|
||||
V_avg_ = np.mean(V_list, dtype=np.float32)
|
||||
V_std_ = np.std(V_list, dtype=np.float32)
|
||||
V_err_ = V_std_/(N_points)**(1/2)
|
||||
return [V_list, V_avg_, V_err_]
|
||||
|
||||
|
||||
# Function to do I-V measurements
|
||||
# Currently doesn't read the voltage that was set, due to issues with querying through mainframe
|
||||
# Errors caluclated incorrectly
|
||||
def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_1 = '', contact_2 = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0):
|
||||
Keithley.clear()
|
||||
print('Measurement started: %s'\
|
||||
%(datetime.datetime.now().strftime("%Hh%Mm%Ss")))
|
||||
V_scan_list = np.linspace(V_start, V_end, int(abs(V_start-V_end)/step_size)+1)
|
||||
for n_l in range(number_of_loops):
|
||||
V_scan_list = np.append(V_scan_list,np.linspace(V_end, V_start, (abs(V_start-V_end)/step_size)+1))
|
||||
print(V_scan_list)
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
|
||||
# open a file to write data to
|
||||
date_today = datetime.date.today() #date for making a directory
|
||||
file_path = Path(__file__).parent / "data" / str(date_today)
|
||||
if not os.path.exists(file_path):#make the directory if it is not there
|
||||
os.mkdir(file_path)
|
||||
time_start = datetime.datetime.now().strftime("%Hh%Mm%Ss")
|
||||
filename_root = "%s_%s_%s_%s_%s_scan_at_%sK_%s" % \
|
||||
(time_start, sample_name, contact_1, contact_2, light, temp, amplifier)
|
||||
filename = filename_root + "_averaging%ss.txt" % (time_average)
|
||||
plotname = filename_root + "_averaging%ss.png" % (time_average)
|
||||
filename2 = filename_root + "_raw.txt"
|
||||
full_name = os.path.join(file_path, filename)
|
||||
full_plotname = os.path.join(file_path, plotname)
|
||||
full_name2 = os.path.join(file_path, filename2)
|
||||
#data_file=open(str(full_name),'w')
|
||||
with open(str(full_name),'w') as data_file, open(str(full_name2),'w') as raw_V_file:
|
||||
data_file.write("Time\tVoltage_source[V]\tVoltage_meas[V]\tVoltage_meas_err[V]\tGain[V/A]\n")
|
||||
raw_V_file.write("Voltage_source[V]\tVoltage_meas[V]\n")
|
||||
# just for ploting here
|
||||
V_plot_list = []
|
||||
V_err_plot_list = []
|
||||
V_scan_plot_list = []
|
||||
# A loop over all currents
|
||||
|
||||
i=0
|
||||
# set_voltage(V_scan_list[0])
|
||||
# time.sleep(5) #wait 3 sec to avoid large noise on first measurement
|
||||
|
||||
for V_scan_item in V_scan_list:
|
||||
|
||||
time_start_iteration= datetime.datetime.now()
|
||||
i = i+1
|
||||
set_voltage(V_scan_item)
|
||||
time.sleep(2) #wait 5 sec for signal to settle
|
||||
# measure+read+write the data
|
||||
V_source = V_scan_item
|
||||
# V_source = read_source_V()
|
||||
[V_list, V_avg, V_err] = measure_V(time_average=time_average, time_interval=0.2)
|
||||
time_now = datetime.datetime.now()
|
||||
data_string = "%s\t %s\t %.5e\t %.5e\t %s\n"\
|
||||
%(time_now, V_source, V_avg, V_err, gain)
|
||||
data_file.write(str(data_string))
|
||||
raw_V_file.write("%s\t %s\n" %(V_source, V_list))
|
||||
V_plot_list.append(V_avg)
|
||||
V_err_plot_list.append(V_err)
|
||||
V_scan_plot_list.append(V_source)
|
||||
|
||||
#make plot
|
||||
plt.close()
|
||||
plt.plot(V_scan_plot_list, V_plot_list,'+')
|
||||
plt.title(str(sample_name))
|
||||
plt.xlabel('Source Voltage / V')
|
||||
plt.ylabel('Measured voltage / V')
|
||||
plt.draw()
|
||||
plt.pause(0.1)
|
||||
plt.show(block=False)
|
||||
iteration_time = datetime.datetime.now()-time_start_iteration
|
||||
remaining_time = iteration_time.total_seconds()*(len(V_scan_list)-i)
|
||||
print(time.strftime('remaining time: %H:%M:%S',\
|
||||
time.gmtime(remaining_time)))
|
||||
|
||||
I_list = [V_plot_list[i]/gain for i in range(len(V_plot_list))]
|
||||
I_err_list = [V_err_plot_list[i]/gain for i in range(len(V_plot_list))]
|
||||
plt.close()
|
||||
plt.figure()
|
||||
plt.errorbar(V_scan_plot_list, I_list, yerr=I_err_list, fmt='+')
|
||||
plt.title(str(sample_name))
|
||||
plt.xlabel('Source Voltage / V')
|
||||
plt.ylabel('I / A')
|
||||
plt.tight_layout()
|
||||
plt.grid()
|
||||
|
||||
plt.savefig(full_plotname)
|
||||
plt.draw()
|
||||
plt.pause(0.001)
|
||||
plt.show(block=False)
|
||||
plt.close()
|
||||
|
||||
data_file.close()
|
||||
raw_V_file.close()
|
||||
set_voltage(0)
|
||||
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
|
||||
print('Source turned off')
|
||||
print('Measurement finished: %s'\
|
||||
%(datetime.datetime.now().strftime("%Hh%Mm%Ss")))
|
||||
return
|
||||
|
||||
# V_start, step size, V_end, time average, sample name, contact 1, contact 2, light, temperature, amplifier, amplifier gain
|
||||
V_scan(-1.0, 0.05, 1.0, .1, "test", "test1", "test1", "MIR", 300, "SR570", 10**(7)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(-1.0, 0.1, 1.0, 1.0, "SHADWELL", "posContactC", "negContactF", "MIR", 18, "SR570", 10**(8)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.1, 1.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.2, -2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.2, 2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.3, -3.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.3, 3.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.5, -5.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
#V_scan(0.0, 0.5, 5.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
|
||||
|
||||
"""
|
||||
# Set up the plot
|
||||
plt.ion() # Enable interactive mode
|
||||
figure, ax = plt.subplots(figsize=(10, 6)) # Create a figure and an axes
|
||||
ax.set_title("Live Number Update")
|
||||
|
||||
# Loop to update the number and plot every second
|
||||
for _ in range(9999): # Limiting to 10 iterations for demonstration
|
||||
number = Keithley_comm.Voltage(Keithley)
|
||||
# Create a new plot for the current number
|
||||
figure, ax = plt.subplots(figsize=(10, 6))
|
||||
ax.text(0.5, 0.5, str(number), fontsize=100, ha='center') # Display the number in the center
|
||||
ax.set_title(f"Number: {number}")
|
||||
ax.axis('off') # Turn off the axis
|
||||
|
||||
plt.show() # Show the plot
|
||||
time.sleep(2) # Pause for a second
|
||||
"""
|
||||
@@ -1,43 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 12:41:44 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Sends a command to the instrument
|
||||
# SIM900 is the VISA resource for the SIM900
|
||||
# port_number is the port number of the instrument to be controlled
|
||||
# instrument_command is the command to be sent
|
||||
def send_command(SIM900, port_number, instrument_command):
|
||||
SIM900_command = "SNDT "+str(port_number)+", \""+instrument_command+"\""
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Send a query to the instrument and get a response - CURRENTLY BROKEN
|
||||
# SIM900 is the VISA resource for the SIM900
|
||||
# port_number is the port number of the instrument to be controlled
|
||||
# instrument_query is the query to be sent
|
||||
# response_bytes is the maximum number of bytes in the response
|
||||
def send_query(SIM900, port_number, instrument_query, response_bytes=7):
|
||||
send_command(SIM900, port_number, instrument_query)
|
||||
SIM900_command = "GETN? "+str(port_number)+", " + str(response_bytes)
|
||||
full_response = SIM900.query(SIM900_command)
|
||||
print("full_response="+full_response)
|
||||
response = full_response[5:]
|
||||
print("response="+response)
|
||||
return(response)
|
||||
|
||||
# Flushes input & output buffers of specified port
|
||||
def flush_port(SIM900, port_number):
|
||||
SIM900_command = "FLSH "+str(port_number)
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Flushes output queue of mainframe
|
||||
def flush_main(SIM900):
|
||||
SIM900_command = "FLOQ"
|
||||
SIM900.write(SIM900_command)
|
||||
|
||||
# Resets all ports
|
||||
def reset(SIM900):
|
||||
SIM900_command = "SRST"
|
||||
SIM900.write(SIM900_command)
|
||||
@@ -1,30 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Oct 10 15:39:12 2022
|
||||
|
||||
@author: gac-x01dc
|
||||
"""
|
||||
|
||||
# Program containing functions with commands for SIM928 voltage source
|
||||
|
||||
# Turns source on/off
|
||||
def V_source_state(on_off = 'off'):
|
||||
command = 'EXON ' + on_off
|
||||
return(command)
|
||||
|
||||
# Set voltage of SIM928
|
||||
def set_voltage(V_value=1e-3):
|
||||
if abs(V_value) < 1e-3:
|
||||
print ('Voltage too low (<|3 mV|), it is set to 0 mV')
|
||||
V_value = 0
|
||||
elif abs(V_value) > 39:
|
||||
print ('Voltage setting too high (>39V), it is set to 39V')
|
||||
V_value = 40e-3
|
||||
V_value = round(V_value,3) # rounding to mV, otherwise the source does not set the voltage because it lacks the precision
|
||||
command = 'VOLT ' + str(V_value) # set voltage
|
||||
return(command)
|
||||
|
||||
# Read voltage set by voltage source
|
||||
def read_voltage():
|
||||
command = 'VOLT?'
|
||||
return(command)
|
||||
@@ -1,130 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "7e9d23ea",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# -*- coding: utf-8 -*-\n",
|
||||
"\"\"\"\n",
|
||||
"Created on Mon Oct 10 16:05:44 2022\n",
|
||||
"\n",
|
||||
"@author: gac-x01dc\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"# Program to do I-V measurements\n",
|
||||
"# Using SIM928 voltage source within SIM900 mainframe\n",
|
||||
"# Using Keithley196 for voltage measurement\n",
|
||||
"\n",
|
||||
"import time\n",
|
||||
"import datetime\n",
|
||||
"import os.path\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import pyvisa\n",
|
||||
"from pathlib import Path\n",
|
||||
"rm = pyvisa.ResourceManager()\n",
|
||||
"\n",
|
||||
"import SIM900_commands as SIM900_comm\n",
|
||||
"import SIM928_commands as SIM928_comm\n",
|
||||
"import Keithley196_commands as Keithley_comm\n",
|
||||
"\n",
|
||||
"Keithley_address = 'TCPIP0::Prologix-00-21-69-01-4e-fb.psi.ch::1234::SOCKET'\n",
|
||||
"# Keithley_address = 'GPIB0::6::INSTR'\n",
|
||||
"SIM900_address = 'TCPIP0::ir-moxa01.psi.ch::3001::SOCKET'#'ASRL1::INSTR'\n",
|
||||
"\n",
|
||||
"Keithley = rm.open_resource(Keithley_address)\n",
|
||||
"SIM900 = rm.open_resource(SIM900_address)\n",
|
||||
"SIM928_port = 1\n",
|
||||
"\n",
|
||||
"# Initialise Keithley\n",
|
||||
"Keithley.clear()\n",
|
||||
"Keithley.timeout = 5000\n",
|
||||
"Keithley.read_termination = '\\n'\n",
|
||||
"Keithley.write(\"T5X\\n\") # Ensures the Keithley reads when it is triggered by \"X\" write\n",
|
||||
"Keithley_comm.Set_Mode(Keithley, \"DC V\")\n",
|
||||
"Keithley_comm.Set_Range(Keithley, \"Auto\")\n",
|
||||
"Keithley.read() # Throwaway\n",
|
||||
"\n",
|
||||
"# Initialise SIM900\n",
|
||||
"SIM900_comm.flush_main(SIM900)\n",
|
||||
"SIM900_comm.reset(SIM900)\n",
|
||||
"SIM900_comm.flush_port(SIM900, SIM928_port)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "91371dcc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"V_value = -0.2\n",
|
||||
"SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.set_voltage(V_value)) # get voltage \n",
|
||||
"\n",
|
||||
"SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state(\"on\"))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5236610b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "9298c70d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"-0.2001732"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# time.sleep(0.1)\n",
|
||||
"Keithley_comm.Voltage(Keithley)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "19bb6089",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "automated-iv-curves",
|
||||
"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.12.13"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user