diff --git a/hp4155/Custom_SMU/debug.ipynb b/hp4155/Custom_SMU/debug.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..6c1bf097ddf3281c4edcacd421d75f2e5da736cd --- /dev/null +++ b/hp4155/Custom_SMU/debug.ipynb @@ -0,0 +1,733 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "8faef648-e31f-48c5-a101-d6070b2d1990", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e492303ec1f2459e9f63b8498bc1129b", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Tab(children=(GridspecLayout(children=(Label(value='UNIT', layout=Layout(grid_area='widget001', height='auto',…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "85f2ead829654b5c857966936ec6680f", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Button(description='Start Measurement', style=ButtonStyle()), Button(description='Import from i…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5c7be71e5aaf426497bd37ba6a4ee6d4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, './lib')\n", + "sys.path.insert(0, '..') #append parent directory\n", + "import os\n", + "import configparser\n", + "import warnings\n", + "\n", + "from interface import *\n", + "from help import *\n", + "import hp4155a\n", + "\n", + "first_page = page_1()\n", + "second_page = page_2()\n", + "third_page = page_3()\n", + "fourth_page = page_4()\n", + "fifth_page = page_5()\n", + "\n", + "titles = [\"SMUs\",\"User Functions\",\"Parameters\",\"Plotting\",\"Save to file\"]\n", + "children = [first_page,second_page,third_page,fourth_page,fifth_page]\n", + "tab = widgets.Tab()\n", + "tab.children = children\n", + "tab.titles = titles\n", + "\n", + "display(tab)\n", + "\n", + "start = widgets.Button(description='Start Measurement')\n", + "ini = widgets.Button(description = 'Import from ini.')\n", + "output = widgets.Output()\n", + "\n", + "display(widgets.HBox([start,ini]),output)\n", + "\n", + "device = hp4155a.HP4155a('GPIB0::17::INSTR')\n", + "\n", + "def on_start_clicked(b):\n", + " with output:\n", + " clear_output()\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = True\n", + " ini.disabled = True\n", + "\n", + " # Reset the device\n", + " device.reset()\n", + " \n", + " # Step 1 create the dictionaries appropriately for every measurement\n", + " \n", + " # read general information\n", + " measurement_mode = third_page[0,0].value\n", + " measurement_name = fifth_page[0,0].value\n", + " processing_nr = fifth_page[1,0].value\n", + " sample_series = fifth_page[2,0].value\n", + " field = fifth_page[3,0].value\n", + " dut = fifth_page[4,0].value\n", + " integration = third_page[0,1].value\n", + "\n", + " # we need constant smus for all measurements\n", + " # Constant Smus\n", + " cons_smus = []\n", + " for j in range(1,5):\n", + " cons_smus.append(create_dict(value = third_page[21,j].value,comp=third_page[22,j].value))\n", + "\n", + " # 2nd page\n", + " user_functions = []\n", + " #iterate over the rows\n", + " for i in range(1,7):\n", + " if second_page[i,0].value!=\"\": # do not save user functions without names\n", + " user_functions.append(\n", + " create_dict(\n", + " name = second_page[i,0].value,\n", + " unit=second_page[i,1].value,\n", + " expression = second_page[i,2].value\n", + " )\n", + " )\n", + "\n", + " # Page 4\n", + " axes = [] # 0 is x-axis , 1 is y1-axis and 2 is y2-axis\n", + " for j in range(1,4): #iterate over the column\n", + " axes.append(\n", + " create_dict(\n", + " name = fourth_page[1,j].value,\n", + " scale = fourth_page[2,j].value,\n", + " min =fourth_page[3,j].value,\n", + " max = fourth_page[4,j].value\n", + " )\n", + " )\n", + "\n", + " # Page 5\n", + " variables = []\n", + " for i in range(8):\n", + " if fifth_page[6+i,0].value!=\"\": # do not save empty rows\n", + " variables.append(\n", + " create_dict(\n", + " name = fifth_page[6+i,0].value,\n", + " unit =fifth_page[6+i,1].value\n", + " )\n", + " )\n", + " \n", + "\n", + " # first sweep\n", + " if measurement_mode == 'SWEEP':\n", + " #page 1\n", + " smus = []\n", + " #iterate over the rows\n", + " for i in range(1,5):\n", + " smus.append(\n", + " create_dict(\n", + " vname = first_page[i,1].value,\n", + " iname = first_page[i,2].value,\n", + " mode = first_page[i,3].value,\n", + " func = first_page[i,4].value,\n", + " disabled = first_page[i,5].value\n", + " )\n", + " )\n", + " \n", + " \n", + " \n", + " # Page 3\n", + " #match hysteris checkbox with the command forwarded to the tool\n", + " if third_page[9,0].value == True:\n", + " hyst = 'DOUB'\n", + " else:\n", + " hyst = 'SING'\n", + " \n", + " var1 = create_dict(\n", + " start = third_page[4,0].value,\n", + " stop = third_page[5,0].value,\n", + " step = third_page[6,0].value,\n", + " comp = third_page[7,0].value,\n", + " pcomp =third_page[8,0].value,\n", + " mode = hyst\n", + " )\n", + " var2 = create_dict(\n", + " start = third_page[4,1].value,\n", + " step = third_page[5,1].value,\n", + " points = third_page[6,1].value,\n", + " comp = third_page[7,1].value,\n", + " pcomp=third_page[8,1].value\n", + " )\n", + " vard = create_dict(\n", + " offset=third_page[4,2].value,\n", + " ratio = third_page[5,2].value,\n", + " comp = third_page[7,2].value,\n", + " pcomp=third_page[8,2].value\n", + " )\n", + " \n", + " pulse = create_dict(\n", + " period=third_page[4,3].value,\n", + " width = third_page[5,3].value,\n", + " base = third_page[6,3].value\n", + " )\n", + "\n", + " # Now execute measurement\n", + "\n", + " #setup sweep measurement mode\n", + " device.measurement_mode('SWE')\n", + "\n", + " #disable all irrelevant units\n", + " device.disable_not_smu()\n", + "\n", + " # First Setup Smus\n", + " for i,smu in enumerate(smus):\n", + " if smu['disabled'] == False:\n", + " device.setup_smu(i+1,smu)\n", + " else: #disabled\n", + " device.smu_disable(i+1)\n", + " \n", + " \n", + " # Setup User Functions\n", + " for user_function in user_functions:\n", + " device.user_function(user_function['name'],user_function['unit'],user_function['expression']) \n", + "\n", + " # Set the integration time\n", + " \n", + " device.integration_time(integration)\n", + " # Setup VAR1 (always in sweep measurements)\n", + " device.setup_var1(var1) # device will check for errors\n", + "\n", + " # Now set the 3 additional columns\n", + " if check_sweep_func(smus,'VAR2') == True:\n", + " device.setup_var2(var2)\n", + " if check_sweep_func(smus,'VARD') == True:\n", + " device.setup_vard(vard)\n", + " if check_sweep_pulse(smus)== True:\n", + " device.setup_pulse(pulse)\n", + "\n", + " # Check for constant SMUs but not grounded\n", + " cons_smu_numbers = check_sweep_cons(smus)\n", + " for i, cons_smu in enumerate(cons_smus):\n", + " if i+1 in cons_smu_numbers: # check if the constant smu was found in the first page func\n", + " device.setup_cons_smu(i+1,cons_smu)\n", + "\n", + " # Now set the axes\n", + " setup_axes(axes,device)\n", + "\n", + " # Set the variables to be saved (This function has an exemption)\n", + " try:\n", + " save_variables(axes,variables,device)\n", + " except Exception as e:\n", + " error_box(e)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + " \n", + "\n", + " # Start the measurement\n", + " device.single_measurement()\n", + " while device.operation_completed()==False:\n", + " pass\n", + " \n", + " device.autoscaling()\n", + "\n", + " # List all errors occured\n", + " counter,message = device.list_all_errors()\n", + " if counter>1:\n", + " error_box(message)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + " \n", + "\n", + " # Get the data from the device \n", + " # These are correcly defined and include the plotted ones\n", + " values = {}\n", + " for variable in variables:\n", + " key = f\"{variable['name']} ({variable['unit']})\"\n", + " values[key] = device.return_values(variable['name'])\n", + "\n", + " plot_results(values,device)\n", + "\n", + " # Save results\n", + " df = pd.DataFrame(values)\n", + "\n", + " filename = f\"{sample_series}_{field}_{dut}_{measurement_name}.txt\"\n", + " txt_file = create_file(filename)\n", + " ini_file = os.path.splitext(txt_file)[0]+'.ini'\n", + "\n", + " with open(txt_file,'w') as f:\n", + " date = str(datetime.today().replace(microsecond=0))\n", + " f.write(f\"{measurement_name} (sweep) at {date}:\"+\"\\n\")\n", + " f.write(\"Sample Information\\n\")\n", + " f.write(f\"Processing Number:{processing_nr}\"+\"\\n\")\n", + " f.write(f\"Sample Series:{sample_series}\"+\"\\n\")\n", + " f.write(f\"Field:{field}\"+\"\\n\")\n", + " f.write(f\"DUT:{dut}\"+\"\\n\")\n", + " f.write(\"\\n\")\n", + " f.write(f\"Measurement parameters can be found at: {ini_file}\"+\"\\n\")\n", + " f.write(\"\\nResults\\n\")\n", + " \n", + " df.to_csv(txt_file,sep=\" \",mode='a')\n", + "\n", + " # export interface to ini file\n", + " # First the Smus\n", + " config = configparser.ConfigParser()\n", + " with open(ini_file,'w') as configfile:\n", + " config.add_section(\"THESE ARE THE PARAMETERS OF THE CORRESPONDING MEASUREMENT\")\n", + " config.add_section(\"THE WHOLE INTERFACE IS SAVED SO FIND WHAT YOU NEED\")\n", + " config.add_section(\"DO NOT MODIFY THIS FILE\")\n", + " config.add_section(f\"MEASUREMENT MODE: {measurement_mode}\")\n", + " config.add_section(f\"INTEGRATION TIME: {integration}\")\n", + " \n", + " # First the smus\n", + " config.add_section(\"SMUS\")\n", + " for i, smu in enumerate(smus):\n", + " config.add_section(f\"SMU{i+1}\")\n", + " for key,value in smu.items():\n", + " config.set(f\"SMU{i+1}\",key,value)\n", + "\n", + " # Secondly the user functions\n", + " config.add_section(\"USER FUNCTIONS\")\n", + " for i, user_function in enumerate(user_functions):\n", + " config.add_section(f\"USER FUNCTION {i+1}\")\n", + " for key,value in user_function.items():\n", + " config.set(f\"USER FUNCTION {i+1}\",key,value)\n", + "\n", + " # Then the 3rd page\n", + " config.add_section(\"VAR1\")\n", + " for key,value in var1.items():\n", + " config.set(\"VAR1\",key,value)\n", + "\n", + " config.add_section(\"VAR2\")\n", + " for key,value in var2.items():\n", + " config.set(\"VAR2\",key,value)\n", + " \n", + " config.add_section(\"VARD\")\n", + " for key, value in vard.items():\n", + " config.set(\"VARD\",key,value)\n", + "\n", + " config.add_section(\"PULSE\")\n", + " for key,value in pulse.items():\n", + " config.set(\"PULSE\",key,value)\n", + " \n", + " # Now The constant smus\n", + " config.add_section('CONSTANT SMUS')\n", + " for i, cons_smu in enumerate(cons_smus):\n", + " config.add_section(f\"CONSTANT SMU{i+1}\")\n", + " for key, value in cons_smu.items():\n", + " config.set(f\"CONSTANT SMU{i+1}\",key,value)\n", + " \n", + "\n", + " # Page 4 The axes\n", + " config.add_section('AXES')\n", + " for i,axis in enumerate(axes):\n", + " config_add_section(f\"AXIS {i+1}\")\n", + " for key,value in axis.items():\n", + " config.set(f\"AXIS {i+1}\",key,value)\n", + " \n", + " # Page 5 The varibles\n", + " config.add_section(\"SAVED VARIABLES\")\n", + " for i, variable in enumerate(variables):\n", + " config.add_section(f\"VARIABLE {i+1}\")\n", + " for key,value in variable.items():\n", + " config.set(f\"VARIABLE {i+1}\",key,value)\n", + "\n", + " config.write(configfile)\n", + " # Sampling Measurement Mode\n", + " elif measurement_mode=='SAMPLING':\n", + " # sampling parameters\n", + " parameters= create_dict(\n", + " mode=third_page[12,0].value,\n", + " interval=third_page[13,0].value,\n", + " hold=third_page[16,0].value,\n", + " points=third_page[14,0].value,\n", + " filter=int(third_page[17,0].value)\n", + " )\n", + " duration = third_page[13,0].value\n", + "\n", + " # Set the smus all constant\n", + " #page 1\n", + " smus = []\n", + " #iterate over the rows and set the function to constant\n", + " for i in range(1,5):\n", + " smus.append(\n", + " create_dict(\n", + " vname = first_page[i,1].value,\n", + " iname = first_page[i,2].value,\n", + " mode = first_page[i,3].value,\n", + " func = 'CONS',\n", + " disabled = first_page[i,5].value\n", + " )\n", + " )\n", + " \n", + " # Now start the measurement\n", + " device.measurement_mode('SAMP')\n", + "\n", + " #disable all irrelevant units\n", + " device.disable_not_smu()\n", + "\n", + " # First Setup Smus\n", + " for i,smu in enumerate(smus):\n", + " if smu['disabled'] == False:\n", + " device.setup_smu(i+1,smu)\n", + " else: #disabled\n", + " device.smu_disable(i+1)\n", + " \n", + " \n", + " # Setup User Functions\n", + " for user_function in user_functions:\n", + " device.user_function(user_function['name'],user_function['unit'],user_function['expression']) \n", + "\n", + " # Set the integration time\n", + " device.integration_time(integration)\n", + "\n", + " # Set the sampling parameters\n", + " device.setup_sampling(parameters)\n", + "\n", + " # Set the total sampling time\n", + " if duration<= 0:\n", + " warnings.warn(\"Non positive measurement duration. Auto Sampling time will be set\")\n", + " device.auto_sampling_time(1)\n", + " else:\n", + " device.total_sampling_time(duration)\n", + "\n", + " # Setup the constant SMUs\n", + " cons_smu_numbers = check_cons_smu_sampling(smus)\n", + " for i, cons_smu in enumerate(smus):\n", + " if i+1 in cons_smu_numbers: # check if the constant smu was found in the first page func\n", + " device.setup_smu_sampling(i+1,cons_smu)\n", + "\n", + " # Set integration time\n", + " device.intergration_time(integration_time)\n", + " \n", + "\n", + "\n", + " # Now set the axes\n", + " setup_axes(axes,device)\n", + "\n", + " # Set the variables to be saved (This function has an exemption)\n", + " try:\n", + " save_variables(axes,variables,device)\n", + " except Exception as e:\n", + " error_box(e)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + " \n", + "\n", + " # Start the measurement\n", + " device.single_measurement()\n", + " while device.operation_completed()==False:\n", + " pass\n", + " \n", + " device.autoscaling()\n", + "\n", + " # List all errors occured\n", + " counter,message = device.list_all_errors()\n", + " if counter>1:\n", + " error_box(message)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + " \n", + "\n", + " # Get the data from the device \n", + " # These are correcly defined and include the plotted ones\n", + " values = {}\n", + " for variable in variables:\n", + " key = f\"{variable['name']} ({variable['unit']})\"\n", + " values[key] = device.return_values(variable['name'])\n", + "\n", + " plot_results(values,device)\n", + "\n", + " # Save results\n", + " df = pd.DataFrame(values)\n", + "\n", + " filename = f\"{sample_series}_{field}_{dut}_{measurement_name}_sampling.txt\"\n", + " txt_file = create_file(filename)\n", + " ini_file = os.path.splitext(txt_file)[0]+'.ini'\n", + "\n", + " with open(txt_file,'w') as f:\n", + " date = str(datetime.today().replace(microsecond=0))\n", + " f.write(f\"{measurement_name} (sampling) at {date}:\"+\"\\n\")\n", + " f.write(\"Sample Information\\n\")\n", + " f.write(f\"Processing Number:{processing_nr}\"+\"\\n\")\n", + " f.write(f\"Sample Series:{sample_series}\"+\"\\n\")\n", + " f.write(f\"Field:{field}\"+\"\\n\")\n", + " f.write(f\"DUT:{dut}\"+\"\\n\")\n", + " f.write(\"\\n\")\n", + " f.write(f\"Measurement parameters can be found at: {ini_file}\"+\"\\n\")\n", + " f.write(\"\\nResults\\n\")\n", + " \n", + " df.to_csv(txt_file,sep=\" \",mode='a')\n", + "\n", + " # export interface to ini file\n", + " # First the Smus\n", + " config = configparser.ConfigParser()\n", + " with open(ini_file,'w') as configfile:\n", + " config.add_section(\"THESE ARE THE PARAMETERS OF THE CORRESPONDING MEASUREMENT\")\n", + " config.add_section(\"THE WHOLE INTERFACE IS SAVED SO FIND WHAT YOU NEED\")\n", + " config.add_section(\"DO NOT MODIFY THIS FILE\")\n", + " config.add_section(f\"MEASUREMENT MODE: {measurement_mode}\")\n", + " config.add_section(f\"INTEGRATION TIME: {integration}\")\n", + " \n", + " # First the smus\n", + " config.add_section(\"SMUS\")\n", + " for i, smu in enumerate(smus):\n", + " config.add_section(f\"SMU{i+1}\")\n", + " for key,value in smu.items():\n", + " config.set(f\"SMU{i+1}\",key,value)\n", + "\n", + " # Secondly the user functions\n", + " config.add_section(\"USER FUNCTIONS\")\n", + " for i, user_function in enumerate(user_functions):\n", + " config.add_section(f\"USER FUNCTION {i+1}\")\n", + " for key,value in user_function.items():\n", + " config.set(f\"USER FUNCTION {i+1}\",key,value)\n", + "\n", + " # Then the 3rd page\n", + " config.add_section('SAMPLING PARAMETERS')\n", + " for key,value in parameters.items():\n", + " config.set('SAMPLING PARAMETERS',key,value)\n", + "\n", + " # Now the constant smus\n", + " config.add_section('CONSTANT SMUS')\n", + " for i, cons_smu in enumerate(cons_smus):\n", + " config.add_section(f\"CONSTANT SMU{i+1}\")\n", + " for key, value in cons_smu.items():\n", + " config.set(f\"CONSTANT SMU{i+1}\",key,value)\n", + " \n", + "\n", + " # Page 4 The axes\n", + " config.add_section('AXES')\n", + " for i,axis in enumerate(axes):\n", + " config_add_section(f\"AXIS {i+1}\")\n", + " for key,value in axis.items():\n", + " config.set(f\"AXIS {i+1}\",key,value)\n", + " \n", + " # Page 5 The varibles\n", + " config.add_section(\"SAVED VARIABLES\")\n", + " for i, variable in enumerate(variables):\n", + " config.add_section(f\"VARIABLE {i+1}\")\n", + " for key,value in variable.items():\n", + " config.set(f\"VARIABLE {i+1}\",key,value)\n", + "\n", + " config.write(configfile)\n", + " else: # Stress\n", + " #page 1\n", + " smus = []\n", + " #iterate over the rows and set the function to constant\n", + " for i in range(1,5):\n", + " # Set SYNC non SYNC mode\n", + " mode= first_page[i,3].value\n", + " if mode != 'COMM':\n", + " func = 'SYNC'\n", + " else:\n", + " func = 'NSYNC'\n", + " smus.append(\n", + " create_dict(\n", + " name = first_page[i,1].value,\n", + " mode = mode,\n", + " func = func,\n", + " disabled = first_page[i,5].value\n", + " )\n", + " )\n", + "\n", + " # Now define the parameters\n", + " duration = third_page[13,0].value\n", + " if duration <= 0:\n", + " error_box(\"Stress Time should be positive!\")\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " return\n", + " hold_time = third_page[16,0].value\n", + " filter = int(third_page[17,0].value)\n", + "\n", + " # Now start the measurement\n", + " device.stress_page()\n", + " device.stress_disable_not_smu()\n", + "\n", + " # First Setup Smus\n", + " for i,smu in enumerate(smus):\n", + " if smu['disabled'] == False:\n", + " device.smu_stress(i+1,smu)\n", + " else: #disabled\n", + " device.smu_stress_disable(i+1)\n", + " \n", + " # Now set the Parameters\n", + " device.stress_filter(filter)\n", + " device.hold_time(hold_time)\n", + " device.stress_time(duration)\n", + "\n", + " cons_smu_numbers = check_cons_smu_sampling(smus) # works also for sampling\n", + " for i, cons_smu in enumerate(smus):\n", + " if i+1 in cons_smu_numbers: # check if the constant smu was found in the first page func\n", + " device.setup_smu_stress(i+1,cons_smu)\n", + " \n", + " # Now start the measurement\n", + " device.start_stress()\n", + " while device.operation_completed() == False:\n", + " pass\n", + " \n", + " # List all errors occured\n", + " counter,message = device.list_all_errors()\n", + " if counter>1:\n", + " error_box(message)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + "\n", + " filename = f\"{sample_series}_{field}_{dut}_{measurement_name}_sweep.txt\"\n", + " txt_file = create_file(filename)\n", + " ini_file = os.path.splitext(txt_file)[0]+'.ini'\n", + "\n", + " with open(txt_file,'w') as f:\n", + " date = str(datetime.today().replace(microsecond=0))\n", + " f.write(f\"{measurement_name} (Stress) at {date}:\"+\"\\n\")\n", + " f.write(\"Sample Information\\n\")\n", + " f.write(f\"Processing Number:{processing_nr}\"+\"\\n\")\n", + " f.write(f\"Sample Series:{sample_series}\"+\"\\n\")\n", + " f.write(f\"Field:{field}\"+\"\\n\")\n", + " f.write(f\"DUT:{dut}\"+\"\\n\")\n", + " f.write(\"\\n\")\n", + " f.write(f\"Measurement parameters can be found at: {ini_file}\"+\"\\n\")\n", + " f.write(\"\\nNo Results Available\\n\")\n", + " \n", + " #export the interface to ini file\n", + " config = configparser.ConfigParser()\n", + " with open(ini_file,'w') as configfile:\n", + " config.add_section(\"THESE ARE THE PARAMETERS OF THE CORRESPONDING MEASUREMENT\")\n", + " config.add_section(\"THE WHOLE INTERFACE IS SAVED SO FIND WHAT YOU NEED\")\n", + " config.add_section(\"DO NOT MODIFY THIS FILE\")\n", + " config.add_section(f\"MEASUREMENT MODE: {measurement_mode}\")\n", + " \n", + " # First the smus\n", + " config.add_section(\"SMUS\")\n", + " for i, smu in enumerate(smus):\n", + " config.add_section(f\"SMU{i+1}\")\n", + " for key,value in smu.items():\n", + " config.set(f\"SMU{i+1}\",key,value)\n", + "\n", + " config.add_section('PARAMETERS')\n", + " config.set('PARAMETERS', \"STRESS TIME\",duration)\n", + " config.set('PARAMETERS', \"HOLD TIME\",hold_time)\n", + " config.set('PARAMETERS', \"FILTER\",filter)\n", + " \n", + " \n", + " # Now the constant smus\n", + " config.add_section('CONSTANT SMUS')\n", + " for i, cons_smu in enumerate(cons_smus):\n", + " config.add_section(f\"CONSTANT SMU{i+1}\")\n", + " for key, value in cons_smu.items():\n", + " config.set(f\"CONSTANT SMU{i+1}\",key,value)\n", + " config.write(configfile)\n", + "\n", + " # End of fuction\n", + " information_box(\"Measurement finished!\")\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return # just to be sure\n", + "\n", + "# This should be tested at the end.\n", + "# After the ini files have been created\n", + "\"\"\"\n", + "def on_ini_clicked(b):\n", + " with output:\n", + " clear_output()\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = True\n", + " ini.disabled = True\n", + "\n", + " #load values to the interface\n", + " config = configparser.ConfigParser()\n", + " try:\n", + " file = load_ini()\n", + " except Exception as e:\n", + " error_box(e)\n", + " change_state(first_page,second_page,third_page,fourth_page,fifth_page)\n", + " start.disabled = False\n", + " ini.disabled = False\n", + " return\n", + " try:\n", + " # Now we do exactly the opposite thing dictionaries to widgets\n", + " #read the values from each section\n", + " config.read(file)\n", + "\n", + " # Get the sections \n", + " sections = config.sections()\n", + " # Get the measurement Mode\n", + " measurement_mode = get_mode(sections)\n", + "\n", + " # Get the constant smus\n", + " for j in range(1,5):\n", + " third_page[21,j].value = config.get(f\"CONSTANT SMU{j}\",'value') \n", + " third_page[22,j].value = config.get(f\"CONSTANT SMU{j}\",'comp')\n", + " \n", + "\n", + " if measurement_mode == 'SWEEP':\n", + " third_page[0,0].value = measurement_mode\n", + " third_page[0,1].value = get_integration(sections)\n", + "\n", + "\"\"\" \n", + " \n", + "start.on_click(on_start_clicked)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/hp4155/Custom_SMU/interface_custom.ipynb b/hp4155/Custom_SMU/interface_custom.ipynb index 660c39a5b730e61b6d05049179956d24802d9df3..52d3d5c36393736e1bba2be07ae80ba59c030541 100644 --- a/hp4155/Custom_SMU/interface_custom.ipynb +++ b/hp4155/Custom_SMU/interface_custom.ipynb @@ -2,14 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "a40693da-961a-434d-89f5-6443c0acb517", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5fc385773f324e7e8311f6f3ee1528f2", + "model_id": "07ccc2d2ed024b878a9d69c3903880e5", "version_major": 2, "version_minor": 0 }, @@ -23,12 +23,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "abd9668c0feb4d8da9566970b335cd5d", + "model_id": "beeb721fca534858b4b08e86adb95e7c", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "Button(description='Start Measurement', style=ButtonStyle())" + "HBox(children=(Button(description='Start Measurement', style=ButtonStyle()), Button(description='Import from i…" ] }, "metadata": {}, @@ -37,7 +37,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ab085a875eae4ea48042af2fcc1c5b49", + "model_id": "6959057ebb5d4959be53648e831ed217", "version_major": 2, "version_minor": 0 }, @@ -56,7 +56,7 @@ { "cell_type": "code", "execution_count": null, - "id": "62768354-a7ff-4f1c-b26a-27fdb88bd545", + "id": "b4134f36-9202-45f5-ad20-b71dfc315edd", "metadata": {}, "outputs": [], "source": [] @@ -78,7 +78,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.0" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/hp4155/Custom_SMU/lib/help.py b/hp4155/Custom_SMU/lib/help.py index 410d038643b4e537997efd761e772206f7603248..a6966441c7d9ab9d38c4efe3b1f2368987f90a50 100644 --- a/hp4155/Custom_SMU/lib/help.py +++ b/hp4155/Custom_SMU/lib/help.py @@ -4,26 +4,27 @@ import pandas as pd import matplotlib.pyplot as plt from IPython.display import clear_output from datetime import datetime +from tkinter import filedialog # Check the functionalities of smus VAR1,VAR2 and VARD def check_sweep_func(smus:list,func:str): for i, smu in enumerate(smus): - if smu["func"] == func: + if smu["func"] == func and smu["disabled"]== False: return True return False # Check if there is a pulsed smu for sweep smu def check_sweep_pulse(smus:list): for smu in smus: - if "PULSE" in smu["mode"]: - return True: + if "PULSE" in smu["mode"] and smu["disabled"]== False: + return True return False # Check if there any constant smus and return their numbers def check_sweep_cons(smus:list): cons_smu_numbers = [] for i,smu in enumerate(smus): - if smu['func']=='CONS' and smu['mode']!='COMM': # Non Grounded SMUs + if (smu['func']=='CONS' and smu['mode']!='COMM') and smu['disabled']== False: # Non Grounded SMUs cons_smu_numbers.append(i+1) # for the actual number of smus return cons_smu_numbers @@ -54,7 +55,7 @@ def save_variables(axes,variables,device): # Retrieve the axes names (variable) axes_names=[] for i,ax in enumerate(axes): - if i != 2 and ax['name']!="" # Y2 axis can be left empty + if i != 2 and ax['name']!="": # Y2 axis can be left empty axes_names.append(ax['name']) # Now Check if axes names are in the variable names @@ -62,11 +63,6 @@ def save_variables(axes,variables,device): if ax_name not in variable_names: raise Exception("Plotted Variables should be saved!") - # Now save the variables - variable_names =[] - for variable in variables: - variable_names.append(variable['name']) - # Send the command to tool device.variables_to_save(variable_names) @@ -99,25 +95,36 @@ def information_box(information): # We plot results: but we will play with the axes! def plot_results(values,device): + # convert scale from tool to matplotlib + def get_scale(scale): + if scale == 'LIN': + scale = 'linear' + else: + scale = 'log' + return scale + # Get the names of the plotted variables x_var = device.get_axis_variable('X') y1_var = device.get_axis_variable('Y1') - y2_var = device.get_axis_variable('Y2') # we will check for the empty + y2_var = device.get_axis_variable('Y2') # Get the scales of the plotted variables - x_scale = device.get_axis_scale('X') # we will check the response too + x_scale = device.get_axis_scale('X') + x_scale = get_scale(x_scale) y1_scale = device.get_axis_scale('Y1') + y1_scale = get_scale(y1_scale) y2_scale = device.get_axis_scale('Y2') + y2_scale = get_scale(y2_scale) # Find the values that will be plotted - for key, results in value.items(): + for key, results in values.items(): if x_var in key: # check if the substring is contained x_values = results.copy() # This is a list x_label = key elif y1_var in key: y1_values = results.copy() y1_label = key - elif y2_var in key and y2_var != None: + elif y2_var in key and y2_var !="": y2_values = results.copy() y2_label = key @@ -132,7 +139,7 @@ def plot_results(values,device): ax1.scatter(x_values,y1_values,color='y') ax1.tick_params(axis ='y', labelcolor ='y',which='both') - if y2_var!= None: + if y2_var!= "": # Adding Twin Axes # Blue color ax2 = ax1.twinx() diff --git a/hp4155/Custom_SMU/main.py b/hp4155/Custom_SMU/main.py index cd7440bf16f1239fd1df8b3c0efddea9e949f74b..81c753e86cc6ac1e4a1c2f2883c6738d3d74e14f 100644 --- a/hp4155/Custom_SMU/main.py +++ b/hp4155/Custom_SMU/main.py @@ -62,7 +62,7 @@ def on_start_clicked(b): user_functions = [] #iterate over the rows for i in range(1,7): - if second_page[i,0]!="": # do not save user functions without names + if second_page[i,0].value!="": # do not save user functions without names user_functions.append( create_dict( name = second_page[i,0].value, @@ -184,7 +184,7 @@ def on_start_clicked(b): # Check for constant SMUs but not grounded cons_smu_numbers = check_sweep_cons(smus) - for i, cons_smu in enumerate(smus): + for i, cons_smu in enumerate(cons_smus): if i+1 in cons_smu_numbers: # check if the constant smu was found in the first page func device.setup_cons_smu(i+1,cons_smu) @@ -286,7 +286,7 @@ def on_start_clicked(b): for key, value in vard.items(): config.set("VARD",key,value) - config.add_section("PULSE"): + config.add_section("PULSE") for key,value in pulse.items(): config.set("PULSE",key,value)