Skip to content

Learning by an example

Olivier Scholder edited this page Sep 20, 2018 · 2 revisions

Import the important libraries

from libgds import gds
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Create custom fonctions

Special shapes can be created by parametric functions. Here is a small example for smileys

def smiley(g, pos, r, dosefactor=1):
    """
    Create a smiley in a GDS file structure
    g: The GDS object
    pos: The position of the smiley
    r: The radius of the smiley
    dosefactor: The dosefactor used in the GDS
    """
    pts = []
    # Create the face frame
    for n in range(41):
        pts += [pos[0]+r*np.cos(np.pi*n/20.0), pos[1]+r*np.sin(np.pi*n/20.0)]
    for n in range(41):
        pts+=[pos[0]+.9*r*np.cos(-np.pi*n/20.0), pos[1]+.9*r*np.sin(-np.pi*n/20.0)]
    g.addPoly(pts, dose=dosefactor)
    
    # Create the eyes
    g.addDisk((pos[0]+.3*r,pos[1]+.4*r), .2*r,40,dose=dosefactor)
    g.addDisk((pos[0]-.3*r,pos[1]+.4*r), .2*r,40,dose=dosefactor)
    
    # Create the mouth
    pts=[]
    for n in range(41):
        pts+=[pos[0]+r*.444*np.cos(np.radians(180+n*180/40.)),pos[1]+r*.444*np.sin(np.radians(180+n*180/40.))]
    for n in range(41):
        pts+=[pos[0]+r*.666*np.cos(np.radians(-n*180/40.)),pos[1]+r*.666*np.sin(np.radians(-n*180/40.))]
    g.addPoly(pts,dose=dosefactor)

def CircleOverlap(C, circles, safety=0):
    """
    Does the circle C overlap with one of the circles?
    C: circle defined by a list (x, y, radius)
    circles: list of circles [(x1, y1, r1), (x2, y2, r2), ...]
    safety: The minimal distance between two circles to concider them as non-overlapping
    """
    for c in circles:
        dx2=(float(C[0])-float(c[0]))**2
        dy2=(float(C[1])-float(c[1]))**2
        dist2 = dx2+dy2
        r2 = (C[2]+c[2]+safety)**2
        if dist2<r2:
            return True
    return False

def RandomSmiley(g, Disks, size, seed=None, safety=500, dosefactor=1):
    """
    Create random, non-overlaping, smileys
    g: the GDS object
    Disks: A dictionary with keys equal to the smiley size and their value for the number of such smileys
    size: The area size (smileys will fill a square of size × size)
    """
    circles = []
    np.random.seed(seed)
    for r in Disks:
        for i in range(Disks[r]):
            isOverlapping = True
            X = []
            Y = []
            while isOverlapping:
                x, y = np.random.randint(r+safety, size-r-safety, 2) # Create random coordinates
                isOverlapping = CircleOverlap((x, y, r), circles, safety=safety)
            circles.append((x, y, r))
            g.uvSave() # Save the uv-coordinates (to restore them later)
            g.uvShift(x, y) # Shift the uv-system such that the 0,0 becomes the center of the smiley
            g.uvRotate(np.random.randint(360)) # Randomly rotate the smiley
            smiley(g, (0, 0), r, dosefactor=dosefactor) # Draw the smiley at uv=(0,0)
            g.uvRestore() # restore uv-system to remove shift and rotation

Creating the GDS data

fig, (ax, ax2) = plt.subplots(1,2,figsize=(20,10))

size = 80000 # nm (=80μm)

AreaDose = 1 #C/m^2 = 100 uC/cm^2
LineDose = 1e-8 # C/m = 100 pC/cm
BeamCurrent = 30*1e-12 # A = 30 pA

g = gds.GDSII()
g.new('Tutorial')
g.newStr('Smiley', ax=ax)
g.addFrame(0, 0, size, size, dose=10)
r = 30000 # 30 μm
smiley(g, (size/2, size/2), r, dosefactor=5)
g.endStr()
g.newStr('Smileys', ax=ax2)
RandomSmiley(g, {10000:2, 5000:10, 2000:20}, size, 1)
g.addFrame(0, 0, size, size, dose=10)
g.endStr()