diff --git a/automated-iv-curves/SIM928_commands.py b/automated-iv-curves/SIM928_commands.py index 5bb1883..696adf3 100755 --- a/automated-iv-curves/SIM928_commands.py +++ b/automated-iv-curves/SIM928_commands.py @@ -15,10 +15,10 @@ def V_source_state(on_off = 'off'): # 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') + print ('\nVoltage 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') + print ('\nVoltage 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 diff --git a/automated-iv-curves/config.toml b/automated-iv-curves/config.toml index d0718cf..51faffc 100644 --- a/automated-iv-curves/config.toml +++ b/automated-iv-curves/config.toml @@ -1,16 +1,16 @@ # Experiment parameters [experiment] -V_start = -1.0 -step_size = 0.5 -V_end = 1.0 -time_average = 3 # time over which to collect voltage average (time per measurement) -sample_name = "test" -contact_1 = "test1" -contact_2 = "test1" -light = "MIR" +V_start = -0.1 +step_size = 0.01 +V_end = 0.1 +time_average = 2 # time over which to collect voltage average (time per measurement) +sample_name = "barrucada?" +contact_pos = "B" +contact_neg = "C" +light = "dark" temp = 300 amplifier = "SR570" -gain = 1e7 # amplifier gain +gain = 1e4 # amplifier gain # Instrument addresses: typically do NOT need to be changed @@ -21,7 +21,7 @@ SIM928_port = 1 # 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(-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 diff --git a/automated-iv-curves/iv_functions.py b/automated-iv-curves/iv_functions.py index 5b75713..8b431bd 100644 --- a/automated-iv-curves/iv_functions.py +++ b/automated-iv-curves/iv_functions.py @@ -90,7 +90,7 @@ def measure_V(time_average=10, time_interval=0.2): # 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): +def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_pos = '', contact_neg = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0): Keithley.clear() # clear the buffer gain = int(gain) # make sure the gain is an Int @@ -106,85 +106,123 @@ def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_nam SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off # open a file to write data to - # file_path = Path(__file__).parent / "data" - # time_start = datetime.datetime.now().strftime("%d%m%Y_%H%M%S") - # filename_root = "iv_%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) + file_path = Path(__file__).parent / "data" + filename_root = "iv_%s_%s_pos%s_neg%s_%s_scan_at_%sK_%s" % \ + (data_id, sample_name, contact_pos, contact_neg, 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") + data_file=open(str(full_name),'w') + + # save metadata before loop + file_path = Path(__file__).parent / "data" + file_path.mkdir(exist_ok=True) + h5_path = file_path / f"{filename[0:-4]}.h5" + with h5py.File(h5_path, "w") as f: + f.attrs["V_start"] = V_start + f.attrs["step_size"] = step_size + f.attrs["V_end"] = V_end + f.attrs["time_average"] = time_average + f.attrs["sample_name"] = sample_name + f.attrs["contact_pos"] = contact_pos + f.attrs["contact_neg"] = contact_neg + f.attrs["light"] = light + f.attrs["temp"] = temp + f.attrs["amplifier"] = amplifier + f.attrs["gain"] = gain + + + 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_avg[V]\tVoltage_meas_err[V]\tGain[V/A]\tVoltage_meas\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: + V_avg_list = [] + V_err_list = [] + V_source_list = [] + V_raw_lists = [] + time_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 + i=0 + for V_scan_item in V_scan_list: + Keithley.clear() + time_start_iteration= datetime.datetime.now() + + 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() + # 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)) + data_string = "%s\t %s\t %.5e\t %.5e\t %s\t %s\n"\ + %(time_now, V_source, V_avg, V_err, gain, V_list) + 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) + V_avg_list.append(V_avg) + V_err_list.append(V_err) + V_source_list.append(V_source) + V_raw_lists.append(V_list) + time_list.append(time_now) - #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))) + #make plot + plt.close() + plt.plot(V_source_list, V_avg_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) + + i = i+1 + 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_avg_list[i]/gain for i in range(len(V_avg_list))] + I_err_list = [V_err_list[i]/gain for i in range(len(V_avg_list))] + + plt.close() + plt.figure() + plt.errorbar(V_source_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() - 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() + data_file.close() # raw_V_file.close() + + file_path = Path(__file__).parent / "data" + file_path.mkdir(exist_ok=True) + + with h5py.File(file_path / f"{filename[0:-4]}.h5", "a") as f: + f.create_dataset("V_source", data=V_source_list) + f.create_dataset("V_avg", data=V_avg_list) + f.create_dataset("V_err", data=V_err_list) + f.create_dataset("V_raw", data=V_raw_lists) + f.create_dataset("timestamps", data=[str(t) for t in time_list]) + f.create_dataset("I", data=I_list) + f.create_dataset("I_err", data=I_err_list) + + + set_voltage(0) SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off diff --git a/automated-iv-curves/iv_run.py b/automated-iv-curves/iv_run.py index 4cc3707..1e1c39d 100644 --- a/automated-iv-curves/iv_run.py +++ b/automated-iv-curves/iv_run.py @@ -2,8 +2,10 @@ import tomllib from iv_functions import V_scan +import h5py with open("automated-iv-curves/config.toml", "rb") as f: cfg = tomllib.load(f) -V_scan(**cfg["experiment"]) \ No newline at end of file +V_scan(**cfg["experiment"]) +