Specific Process Knowledge/Etch/DRIE-Pegasus/Claritas: Difference between revisions

From LabAdviser
Jmli (talk | contribs)
Blanked the page
Tag: Blanking
Jmli (talk | contribs)
No edit summary
Line 1: Line 1:
<syntaxhighlight lang="python" line>


import SEM_API_fix as SEM_API
import matplotlib.pyplot as plt
import numpy as np
import time
import math
from contextlib import contextmanager
import tkinter as tk
from tkinter import StringVar
class Col_WD:
    def __init__(self, inputImages, inputOverlaps):
        self.var_WD0_str = StringVar()
        self.var_WD_0 = 1
        self.var_WDext_str = StringVar()
        self.var_WD_ext = 1
        self.var_WDwob_str = StringVar()
        self.var_Unshake_str = StringVar()
        self.var_inputImages = inputImages 
        self.var_inputOverlaps = inputOverlaps 
    def button_WD0set(self):
        with SEM_API.SEM_API("local") as sem:
            self.var_WD_0 = sem.GetValue("AP_WD")
            self.var_WD0_str.set("WD_0="+ str(round(self.var_WD_0*1000,3))+"mm")
   
    def button_WDextSet(self):
        with SEM_API.SEM_API("local") as sem:
            WDget = sem.GetValue("AP_WD")
            self.var_WD_ext = abs(round((WDget-self.var_WD_0)/self.var_WD_0*100,3))
            self.var_WDext_str.set("WD_range="+ str(self.var_WD_ext)+"%")
   
    def button_WDwob(self):
        # Set the initial conditions
        set_conditions()
        # Calculate the total number of images and the working distance factor
        total_images = int(round(self.var_inputImages))
        wd_factor = self.var_WD_ext / 100
        overlap_difference = self.var_inputImages - self.var_inputOverlaps
        # Use context manager to handle SEM_API connection once
        with SEM_API.SEM_API("local") as sem:
            for i in range(total_images):
                # Calculate the working distance once per iteration
                wd = self.var_WD_0 * (1 + wd_factor * math.sin(2 * math.pi * i / overlap_difference))
                sem.SetValue("AP_WD", wd)
                # Call the function to acquire the image
                acquire_image()
                # Update the progress
                print(f"# {i + 1} of {total_images} done")
        # Update the GUI
        self.var_WDwob_str.set("Shake completed")
   
    def button_Unshake(self):
        self.var_Unshake_str.set("Unshaking no working")
class Col_AP:
    def __init__(self, inputImages, inputOverlaps):
        self.var_AP0_str = StringVar()
        self.var_AP_0 = 1
        self.var_APext_str = StringVar()
        self.var_APext = 1
        self.var_APwobX_str = StringVar()
        self.var_APwobY_str = StringVar()
        self.var_inputImages = inputImages 
        self.var_inputOverlaps = inputOverlaps
       
    def button_AP0(self):
        with SEM_API.SEM_API("local") as sem:
            self.var_AP_0 = sem.GetValue("AP_APERTURE_ALIGN_X")
            self.var_WD0_str.set("WD_0="+ str(round(self.var_WD_0*1000,3))+"mm")
        self.var_AP0_str.set("Button 5 Pressed")
   
    def button_APext(self):
        self.var_APext_str.set("Button 6 Pressed")
   
    def button_APwobX(self):
        self.var_APwobX_str.set("Button 7 Pressed")
   
    def button_APwobY(self):
       
        self.var_APwobY_str.set("Button 8 Pressed")
class Col_Stig:
    def __init__(self, inputImages, inputOverlaps):
        self.var1 = StringVar()
        self.var2 = StringVar()
        self.var3 = StringVar()
        self.var4 = StringVar()
        self.inputImages = inputImages 
        self.inputOverlaps = inputOverlaps
    def button_Stig0(self):
        #sem.GetValue("AP_STIG_X")
        self.var1.set("Button 9 Pressed")
   
    def button_Stigext(self):
        self.var2.set("Button 10 Pressed")
   
    def button_StigwobX(self):
        self.var3.set("Button 11 Pressed")
   
    def button_StigwobY(self):
        self.var4.set("Button 12 Pressed")
def set_conditions():
    with SEM_API.SEM_API("local") as sem:
        sem.SetValue("DP_IMAGE_STORE",1)
        sem.Execute("CMD_MODE_NORMAL")
        sem.Execute("CMD_SCANRATE8")       
        sem.Execute("CMD_UNFREEZE_ALL")
def acquire_image():
    # Call to the SEM API has been done prior to this function
    with SEM_API.SEM_API("local") as sem:
        sem.Execute("CMD_UNFREEZE_ALL")
        time.sleep(0.1)  # wait briefly before freezing
        sem.Execute("CMD_FREEZE_ALL")
   
        # Check for the beam to be unblanked, avoiding excessive waiting
        while sem.GetState("DP_BEAM_BLANKED") == "No":
            time.sleep(1)  # reduced wait time in the loop for efficiency
   
        # Execute the photo-taking command
        sem.Execute("CMD_TAKE_PHOTO")
def create_gui():
    root = tk.Tk()
    root.title("SEM Shaker 2")
    # Input fields with labels
    tk.Label(root, text="# images:").grid(row=0, column=0)
    inputImages_entry = tk.Entry(root)
    inputImages_entry.grid(row=0, column=1)
    tk.Label(root, text="# overlaps:").grid(row=1, column=0)
    inputOverlaps_entry = tk.Entry(root)
    inputOverlaps_entry.grid(row=1, column=1)
    # Function to update input values
    def update_inputs():
        try:
            inputImages = float(inputImages_entry.get())
            inputOverlaps = float(inputOverlaps_entry.get())
        except ValueError:
            return
    # Create instances of each column class
        column1 = Col_WD(inputImages, inputOverlaps)
        column2 = Col_AP(inputImages, inputOverlaps)
        column3 = Col_Stig(inputImages, inputOverlaps)
    # Buttons and corresponding labels
        #buttons = [
        #    [(column1.button_WD0set, column1.var_WD0_str), (column2.button_AP0, column2.var_AP0_str), (column3.button_Stig0, column3.var1)],
        #    [(column1.button_WDextSet, column1.var_WDext_str), (column2.button_APext, column2.var_APext_str), (column3.button_Stigext, column3.var2)],
        #    [(column1.button_WDwob, column1.var_WDwob_str), (column2.button_APwobX, column2.var_APwobX_str), (column3.button_StigwobX, column3.var3)],
        #    [(column1.button_Unshake, column1.var_Unshake_str), (column2.button_APwobY, column2.var_APwobY_str), (column3.button_StigwobY, column3.var4)]
        #]
        button = tk.Button(root, text=f"WD_0", command=column1.button_WD0set)
        button.grid(row=3, column=1)
        label = tk.Label(root, textvariable=column1.var_WD0_str)
        label.grid(row=7, column=1)
        button = tk.Button(root, text=f"AP_0", command=column2.button_AP0)
        button.grid(row=3, column=2)
        label = tk.Label(root, textvariable=column2.var_AP0_str)
        label.grid(row=7, column=2)
        button = tk.Button(root, text=f"Stig_0", command=column3.button_Stig0)
        button.grid(row=3, column=3)
        label = tk.Label(root, textvariable=column3.var1)
        label.grid(row=7, column=3)
        button = tk.Button(root, text=f"WD_rng", command=column1.button_WDextSet)
        button.grid(row=4, column=1)
        label = tk.Label(root, textvariable=column1.var_WDext_str)
        label.grid(row=8, column=1)
        button = tk.Button(root, text=f"AP_rng", command=column2.button_APext)
        button.grid(row=4, column=2)
        label = tk.Label(root, textvariable=column2.var_APext_str)
        label.grid(row=8, column=2)
        button = tk.Button(root, text=f"Stig_rng", command=column3.button_Stigext)
        button.grid(row=4, column=3)
        label = tk.Label(root, textvariable=column3.var2)
        label.grid(row=8, column=3)
        button = tk.Button(root, text=f"Shake WD", command=column1.button_WDwob)
        button.grid(row=5, column=1)
        label = tk.Label(root, textvariable=column1.var_WDwob_str)
        label.grid(row=9, column=1)
        button = tk.Button(root, text=f"Shake AP X", command=column2.button_APwobX)
        button.grid(row=5, column=2)
        label = tk.Label(root, textvariable=column2.var_APwobX_str)
        label.grid(row=9, column=2)
        button = tk.Button(root, text=f"Shake Stig X", command=column3.button_StigwobX)
        button.grid(row=5, column=3)
        label = tk.Label(root, textvariable=column3.var3)
        label.grid(row=9, column=3)
        button = tk.Button(root, text=f"Unshake", command=column1.button_Unshake)
        button.grid(row=6, column=1)
        label = tk.Label(root, textvariable=column1.var_Unshake_str)
        label.grid(row=10, column=1)
        button = tk.Button(root, text=f"Shake AP Y", command=column2.button_APwobY)
        button.grid(row=6, column=2)
        label = tk.Label(root, textvariable=column2.var_APwobY_str)
        label.grid(row=10, column=2)
        button = tk.Button(root, text=f"Shake Stig Y", command=column3.button_StigwobY)
        button.grid(row=6, column=3)
        label = tk.Label(root, textvariable=column3.var4)
        label.grid(row=10, column=3)
    # Button to update inputs and create button actions
    update_button = tk.Button(root, text="Update Inputs", command=update_inputs)
    update_button.grid(row=2, column=1)
    root.mainloop()
#if __name__ == "__main__":
create_gui()
</syntaxhighlight>

Revision as of 14:22, 24 September 2024

import SEM_API_fix as SEM_API
import matplotlib.pyplot as plt
import numpy as np
import time 
import math
from contextlib import contextmanager

import tkinter as tk
from tkinter import StringVar

class Col_WD:
    def __init__(self, inputImages, inputOverlaps):
        self.var_WD0_str = StringVar()
        self.var_WD_0 = 1
        self.var_WDext_str = StringVar()
        self.var_WD_ext = 1
        self.var_WDwob_str = StringVar()
        self.var_Unshake_str = StringVar()
        self.var_inputImages = inputImages  
        self.var_inputOverlaps = inputOverlaps  

    def button_WD0set(self):
        with SEM_API.SEM_API("local") as sem:
            self.var_WD_0 = sem.GetValue("AP_WD")
            self.var_WD0_str.set("WD_0="+ str(round(self.var_WD_0*1000,3))+"mm")
    
    def button_WDextSet(self):
        with SEM_API.SEM_API("local") as sem:
            WDget = sem.GetValue("AP_WD")
            self.var_WD_ext = abs(round((WDget-self.var_WD_0)/self.var_WD_0*100,3))
            self.var_WDext_str.set("WD_range="+ str(self.var_WD_ext)+"%")
    
    def button_WDwob(self):
        # Set the initial conditions
        set_conditions()
        # Calculate the total number of images and the working distance factor
        total_images = int(round(self.var_inputImages))
        wd_factor = self.var_WD_ext / 100
        overlap_difference = self.var_inputImages - self.var_inputOverlaps

        # Use context manager to handle SEM_API connection once
        with SEM_API.SEM_API("local") as sem:
            for i in range(total_images):
                # Calculate the working distance once per iteration
                wd = self.var_WD_0 * (1 + wd_factor * math.sin(2 * math.pi * i / overlap_difference))
                sem.SetValue("AP_WD", wd)
                # Call the function to acquire the image
                acquire_image() 
                # Update the progress
                print(f"# {i + 1} of {total_images} done")
        # Update the GUI
        self.var_WDwob_str.set("Shake completed")
    
    def button_Unshake(self):
        self.var_Unshake_str.set("Unshaking no working")

class Col_AP:
    def __init__(self, inputImages, inputOverlaps):
        self.var_AP0_str = StringVar()
        self.var_AP_0 = 1
        self.var_APext_str = StringVar()
        self.var_APext = 1
        self.var_APwobX_str = StringVar()
        self.var_APwobY_str = StringVar()
        self.var_inputImages = inputImages  
        self.var_inputOverlaps = inputOverlaps 
        
    def button_AP0(self):
        with SEM_API.SEM_API("local") as sem:
            self.var_AP_0 = sem.GetValue("AP_APERTURE_ALIGN_X")
            self.var_WD0_str.set("WD_0="+ str(round(self.var_WD_0*1000,3))+"mm")

        self.var_AP0_str.set("Button 5 Pressed")
    
    def button_APext(self):
        self.var_APext_str.set("Button 6 Pressed")
    
    def button_APwobX(self):
        self.var_APwobX_str.set("Button 7 Pressed")
    
    def button_APwobY(self):
        
        self.var_APwobY_str.set("Button 8 Pressed")

class Col_Stig:
    def __init__(self, inputImages, inputOverlaps):
        self.var1 = StringVar()
        self.var2 = StringVar()
        self.var3 = StringVar()
        self.var4 = StringVar()
        self.inputImages = inputImages  
        self.inputOverlaps = inputOverlaps

    def button_Stig0(self):
        #sem.GetValue("AP_STIG_X")
        self.var1.set("Button 9 Pressed")
    
    def button_Stigext(self):
        self.var2.set("Button 10 Pressed")
    
    def button_StigwobX(self):
        self.var3.set("Button 11 Pressed")
    
    def button_StigwobY(self):
        self.var4.set("Button 12 Pressed")

def set_conditions():
    with SEM_API.SEM_API("local") as sem:
        sem.SetValue("DP_IMAGE_STORE",1)
        sem.Execute("CMD_MODE_NORMAL")
        sem.Execute("CMD_SCANRATE8")        
        sem.Execute("CMD_UNFREEZE_ALL")

def acquire_image():
    # Call to the SEM API has been done prior to this function
    with SEM_API.SEM_API("local") as sem:
        sem.Execute("CMD_UNFREEZE_ALL")
        time.sleep(0.1)  # wait briefly before freezing
        sem.Execute("CMD_FREEZE_ALL")
    
        # Check for the beam to be unblanked, avoiding excessive waiting
        while sem.GetState("DP_BEAM_BLANKED") == "No":
            time.sleep(1)  # reduced wait time in the loop for efficiency
    
        # Execute the photo-taking command
        sem.Execute("CMD_TAKE_PHOTO") 

def create_gui():
    root = tk.Tk()
    root.title("SEM Shaker 2")

    # Input fields with labels
    tk.Label(root, text="# images:").grid(row=0, column=0)
    inputImages_entry = tk.Entry(root)
    inputImages_entry.grid(row=0, column=1)

    tk.Label(root, text="# overlaps:").grid(row=1, column=0)
    inputOverlaps_entry = tk.Entry(root)
    inputOverlaps_entry.grid(row=1, column=1)

    # Function to update input values
    def update_inputs():
        try:
            inputImages = float(inputImages_entry.get())
            inputOverlaps = float(inputOverlaps_entry.get())
        except ValueError:
            return

    # Create instances of each column class
        column1 = Col_WD(inputImages, inputOverlaps)
        column2 = Col_AP(inputImages, inputOverlaps)
        column3 = Col_Stig(inputImages, inputOverlaps)

    # Buttons and corresponding labels
        #buttons = [
        #    [(column1.button_WD0set, column1.var_WD0_str), (column2.button_AP0, column2.var_AP0_str), (column3.button_Stig0, column3.var1)],
        #    [(column1.button_WDextSet, column1.var_WDext_str), (column2.button_APext, column2.var_APext_str), (column3.button_Stigext, column3.var2)],
        #    [(column1.button_WDwob, column1.var_WDwob_str), (column2.button_APwobX, column2.var_APwobX_str), (column3.button_StigwobX, column3.var3)],
        #    [(column1.button_Unshake, column1.var_Unshake_str), (column2.button_APwobY, column2.var_APwobY_str), (column3.button_StigwobY, column3.var4)]
        #]

        button = tk.Button(root, text=f"WD_0", command=column1.button_WD0set)
        button.grid(row=3, column=1)
        label = tk.Label(root, textvariable=column1.var_WD0_str)
        label.grid(row=7, column=1)

        button = tk.Button(root, text=f"AP_0", command=column2.button_AP0)
        button.grid(row=3, column=2)
        label = tk.Label(root, textvariable=column2.var_AP0_str)
        label.grid(row=7, column=2)

        button = tk.Button(root, text=f"Stig_0", command=column3.button_Stig0)
        button.grid(row=3, column=3)
        label = tk.Label(root, textvariable=column3.var1)
        label.grid(row=7, column=3)

        button = tk.Button(root, text=f"WD_rng", command=column1.button_WDextSet)
        button.grid(row=4, column=1)
        label = tk.Label(root, textvariable=column1.var_WDext_str)
        label.grid(row=8, column=1)

        button = tk.Button(root, text=f"AP_rng", command=column2.button_APext)
        button.grid(row=4, column=2)
        label = tk.Label(root, textvariable=column2.var_APext_str)
        label.grid(row=8, column=2)

        button = tk.Button(root, text=f"Stig_rng", command=column3.button_Stigext)
        button.grid(row=4, column=3)
        label = tk.Label(root, textvariable=column3.var2)
        label.grid(row=8, column=3)

        button = tk.Button(root, text=f"Shake WD", command=column1.button_WDwob)
        button.grid(row=5, column=1)
        label = tk.Label(root, textvariable=column1.var_WDwob_str)
        label.grid(row=9, column=1)

        button = tk.Button(root, text=f"Shake AP X", command=column2.button_APwobX)
        button.grid(row=5, column=2)
        label = tk.Label(root, textvariable=column2.var_APwobX_str)
        label.grid(row=9, column=2)

        button = tk.Button(root, text=f"Shake Stig X", command=column3.button_StigwobX)
        button.grid(row=5, column=3)
        label = tk.Label(root, textvariable=column3.var3)
        label.grid(row=9, column=3)

        button = tk.Button(root, text=f"Unshake", command=column1.button_Unshake)
        button.grid(row=6, column=1)
        label = tk.Label(root, textvariable=column1.var_Unshake_str)
        label.grid(row=10, column=1)

        button = tk.Button(root, text=f"Shake AP Y", command=column2.button_APwobY)
        button.grid(row=6, column=2)
        label = tk.Label(root, textvariable=column2.var_APwobY_str)
        label.grid(row=10, column=2)

        button = tk.Button(root, text=f"Shake Stig Y", command=column3.button_StigwobY)
        button.grid(row=6, column=3)
        label = tk.Label(root, textvariable=column3.var4)
        label.grid(row=10, column=3)

    # Button to update inputs and create button actions
    update_button = tk.Button(root, text="Update Inputs", command=update_inputs)
    update_button.grid(row=2, column=1)

    root.mainloop()

#if __name__ == "__main__":
create_gui()