PEP8 formatting

This commit is contained in:
Matthew Guthaus 2019-11-07 16:48:37 +00:00
parent 0dea153919
commit 32f1cde897
1 changed files with 120 additions and 107 deletions

View File

@ -11,6 +11,7 @@ from vector import vector
from tech import layer
import math
class pin_layout:
"""
A class to represent a rectangular design pin. It is limited to a
@ -20,40 +21,45 @@ class pin_layout:
def __init__(self, name, rect, layer_name_pp):
self.name = name
# repack the rect as a vector, just in case
if type(rect[0])==vector:
if type(rect[0]) == vector:
self.rect = rect
else:
self.rect = [vector(rect[0]),vector(rect[1])]
self.rect = [vector(rect[0]), vector(rect[1])]
# snap the rect to the grid
self.rect = [x.snap_to_grid() for x in self.rect]
debug.check(self.width()>0,"Zero width pin.")
debug.check(self.height()>0,"Zero height pin.")
debug.check(self.width() > 0,"Zero width pin.")
debug.check(self.height() > 0,"Zero height pin.")
# if it's a string, use the name
if type(layer_name_pp)==str:
self.layer=layer_name_pp
if type(layer_name_pp) == str:
self.layer = layer_name_pp
# else it is required to be a lpp
else:
for (layer_name, lpp) in layer.items():
if layer_name_pp[0]==lpp[0] and (layer_name_pp[1]==None or layer_name_pp[1]==lpp[1]):
self.layer=layer_name
if layer_name_pp[0] == lpp[0] and (not layer_name_pp[1] or layer_name_pp[1]==lpp[1]):
self.layer = layer_name
break
else:
debug.error("Couldn't find layer {}".format(layer_name_pp),-1)
debug.error("Couldn't find layer {}".format(layer_name_pp), -1)
self.lpp = layer[self.layer]
def __str__(self):
""" override print function output """
return "({} layer={} ll={} ur={})".format(self.name,self.layer,self.rect[0],self.rect[1])
return "({} layer={} ll={} ur={})".format(self.name,
self.layer,
self.rect[0],
self.rect[1])
def __repr__(self):
"""
override repr function output (don't include
"""
override repr function output (don't include
name since pin shapes could have same shape but diff name e.g. blockage vs A)
"""
return "(layer={} ll={} ur={})".format(self.layer,self.rect[0],self.rect[1])
return "(layer={} ll={} ur={})".format(self.layer,
self.rect[0],
self.rect[1])
def __hash__(self):
""" Implement the hash function for sets etc. """
@ -72,15 +78,15 @@ class pin_layout:
def __eq__(self, other):
""" Check if these are the same pins for duplicate checks """
if isinstance(other, self.__class__):
return (self.layer==other.layer and self.rect == other.rect)
return (self.layer == other.layer and self.rect == other.rect)
else:
return False
return False
def bbox(self, pin_list):
"""
Given a list of layout pins, create a bounding box layout.
"""
(ll, ur) = self.rect
(ll, ur) = self.rect
min_x = ll.x
max_x = ur.x
min_y = ll.y
@ -92,17 +98,17 @@ class pin_layout:
min_y = min(min_y, pin.ll().y)
max_y = max(max_y, pin.ur().y)
self.rect = [vector(min_x,min_y),vector(max_x,max_y)]
self.rect = [vector(min_x, min_y), vector(max_x, max_y)]
def inflate(self, spacing=None):
"""
Inflate the rectangle by the spacing (or other rule)
and return the new rectangle.
"""
Inflate the rectangle by the spacing (or other rule)
and return the new rectangle.
"""
if not spacing:
spacing = 0.5*drc("{0}_to_{0}".format(self.layer))
(ll,ur) = self.rect
(ll, ur) = self.rect
spacing = vector(spacing, spacing)
newll = ll - spacing
newur = ur + spacing
@ -111,20 +117,20 @@ class pin_layout:
def intersection(self, other):
""" Check if a shape overlaps with a rectangle """
(ll,ur) = self.rect
(oll,our) = other.rect
(ll, ur) = self.rect
(oll, our) = other.rect
min_x = max(ll.x, oll.x)
max_x = min(ll.x, oll.x)
min_y = max(ll.y, oll.y)
max_y = min(ll.y, oll.y)
return [vector(min_x,min_y),vector(max_x,max_y)]
return [vector(min_x, min_y), vector(max_x, max_y)]
def xoverlaps(self, other):
""" Check if shape has x overlap """
(ll,ur) = self.rect
(oll,our) = other.rect
(ll, ur) = self.rect
(oll, our) = other.rect
x_overlaps = False
# check if self is within other x range
if (ll.x >= oll.x and ll.x <= our.x) or (ur.x >= oll.x and ur.x <= our.x):
@ -137,8 +143,8 @@ class pin_layout:
def yoverlaps(self, other):
""" Check if shape has x overlap """
(ll,ur) = self.rect
(oll,our) = other.rect
(ll, ur) = self.rect
(oll, our) = other.rect
y_overlaps = False
# check if self is within other y range
@ -152,15 +158,15 @@ class pin_layout:
def xcontains(self, other):
""" Check if shape contains the x overlap """
(ll,ur) = self.rect
(oll,our) = other.rect
(ll, ur) = self.rect
(oll, our) = other.rect
return (oll.x >= ll.x and our.x <= ur.x)
def ycontains(self, other):
""" Check if shape contains the y overlap """
(ll,ur) = self.rect
(oll,our) = other.rect
(ll, ur) = self.rect
(oll, our) = other.rect
return (oll.y >= ll.y and our.y <= ur.y)
@ -189,7 +195,6 @@ class pin_layout:
return True
return False
def overlaps(self, other):
""" Check if a shape overlaps with a rectangle """
# Can only overlap on the same layer
@ -215,40 +220,45 @@ class pin_layout:
def normalize(self):
""" Re-find the LL and UR points after a transform """
(first,second)=self.rect
ll = vector(min(first[0],second[0]),min(first[1],second[1]))
ur = vector(max(first[0],second[0]),max(first[1],second[1]))
self.rect=[ll,ur]
(first, second) = self.rect
ll = vector(min(first[0], second[0]), min(first[1], second[1]))
ur = vector(max(first[0], second[0]), max(first[1], second[1]))
self.rect=[ll, ur]
def transform(self,offset,mirror,rotate):
""" Transform with offset, mirror and rotation to get the absolute pin location.
We must then re-find the ll and ur. The master is the cell instance. """
(ll,ur) = self.rect
if mirror=="MX":
ll=ll.scale(1,-1)
ur=ur.scale(1,-1)
elif mirror=="MY":
ll=ll.scale(-1,1)
ur=ur.scale(-1,1)
elif mirror=="XY":
ll=ll.scale(-1,-1)
ur=ur.scale(-1,-1)
def transform(self, offset, mirror, rotate):
"""
Transform with offset, mirror and rotation
to get the absolute pin location.
We must then re-find the ll and ur.
The master is the cell instance.
"""
(ll, ur) = self.rect
if mirror == "MX":
ll = ll.scale(1, -1)
ur = ur.scale(1, -1)
elif mirror == "MY":
ll = ll.scale(-1, 1)
ur = ur.scale(-1, 1)
elif mirror == "XY":
ll = ll.scale(-1, -1)
ur = ur.scale(-1, -1)
if rotate==90:
ll=ll.rotate_scale(-1,1)
ur=ur.rotate_scale(-1,1)
elif rotate==180:
ll=ll.scale(-1,-1)
ur=ur.scale(-1,-1)
elif rotate==270:
ll=ll.rotate_scale(1,-1)
ur=ur.rotate_scale(1,-1)
if rotate == 90:
ll = ll.rotate_scale(-1, 1)
ur = ur.rotate_scale(-1, 1)
elif rotate == 180:
ll = ll.scale(-1, -1)
ur = ur.scale(-1, -1)
elif rotate == 270:
ll = ll.rotate_scale(1, -1)
ur = ur.rotate_scale(1, -1)
self.rect=[offset+ll,offset+ur]
self.rect = [offset + ll, offset + ur]
self.normalize()
def center(self):
return vector(0.5*(self.rect[0].x+self.rect[1].x),0.5*(self.rect[0].y+self.rect[1].y))
return vector(0.5*(self.rect[0].x+self.rect[1].x),
0.5*(self.rect[0].y+self.rect[1].y))
def cx(self):
""" Center x """
@ -265,17 +275,17 @@ class pin_layout:
def ul(self):
""" Upper left point """
return vector(self.rect[0].x,self.rect[1].y)
return vector(self.rect[0].x, self.rect[1].y)
def lr(self):
""" Lower right point """
return vector(self.rect[1].x,self.rect[0].y)
return vector(self.rect[1].x, self.rect[0].y)
def ur(self):
""" Upper right point """
return self.rect[1]
# The possible y edge values
# The possible y edge values
def uy(self):
""" Upper y value """
return self.rect[1].y
@ -294,30 +304,33 @@ class pin_layout:
""" Right x value """
return self.rect[1].x
# The edge centers
def rc(self):
""" Right center point """
return vector(self.rect[1].x,0.5*(self.rect[0].y+self.rect[1].y))
return vector(self.rect[1].x,
0.5*(self.rect[0].y+self.rect[1].y))
def lc(self):
""" Left center point """
return vector(self.rect[0].x,0.5*(self.rect[0].y+self.rect[1].y))
return vector(self.rect[0].x,
0.5*(self.rect[0].y+self.rect[1].y))
def uc(self):
""" Upper center point """
return vector(0.5*(self.rect[0].x+self.rect[1].x),self.rect[1].y)
return vector(0.5*(self.rect[0].x+self.rect[1].x),
self.rect[1].y)
def bc(self):
""" Bottom center point """
return vector(0.5*(self.rect[0].x+self.rect[1].x),self.rect[0].y)
return vector(0.5*(self.rect[0].x+self.rect[1].x),
self.rect[0].y)
def gds_write_file(self, newLayout):
"""Writes the pin shape and label to GDS"""
debug.info(4, "writing pin (" + str(self.layer) + "):"
+ str(self.width()) + "x" + str(self.height()) + " @ " + str(self.ll()))
(layer_num,purpose) = layer[self.layer]
debug.info(4, "writing pin (" + str(self.layer) + "):"
+ str(self.width()) + "x"
+ str(self.height()) + " @ " + str(self.ll()))
(layer_num, purpose) = layer[self.layer]
newLayout.addBox(layerNumber=layer_num,
purposeNumber=purpose,
offsetInMicrons=self.ll(),
@ -325,37 +338,37 @@ class pin_layout:
height=self.height(),
center=False)
# Add the tet in the middle of the pin.
# This fixes some pin label offsetting when GDS gets imported into Magic.
# This fixes some pin label offsetting when GDS gets
# imported into Magic.
newLayout.addText(text=self.name,
layerNumber=layer_num,
purposeNumber=purpose,
offsetInMicrons=self.center(),
magnification=GDS["zoom"],
rotate=None)
def compute_overlap(self, other):
""" Calculate the rectangular overlap of two rectangles. """
(r1_ll,r1_ur) = self.rect
(r2_ll,r2_ur) = other.rect
(r1_ll, r1_ur) = self.rect
(r2_ll, r2_ur) = other.rect
#ov_ur = vector(min(r1_ur.x,r2_ur.x),min(r1_ur.y,r2_ur.y))
#ov_ll = vector(max(r1_ll.x,r2_ll.x),max(r1_ll.y,r2_ll.y))
# ov_ur = vector(min(r1_ur.x,r2_ur.x),min(r1_ur.y,r2_ur.y))
# ov_ll = vector(max(r1_ll.x,r2_ll.x),max(r1_ll.y,r2_ll.y))
dy = min(r1_ur.y,r2_ur.y)-max(r1_ll.y,r2_ll.y)
dx = min(r1_ur.x,r2_ur.x)-max(r1_ll.x,r2_ll.x)
dy = min(r1_ur.y, r2_ur.y) - max(r1_ll.y, r2_ll.y)
dx = min(r1_ur.x, r2_ur.x) - max(r1_ll.x, r2_ll.x)
if dx>=0 and dy>=0:
return [dx,dy]
if dx >= 0 and dy >= 0:
return [dx, dy]
else:
return [0,0]
return [0, 0]
def distance(self, other):
"""
"""
Calculate the distance to another pin layout.
"""
(r1_ll,r1_ur) = self.rect
(r2_ll,r2_ur) = other.rect
(r1_ll, r1_ur) = self.rect
(r2_ll, r2_ur) = other.rect
def dist(x1, y1, x2, y2):
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
@ -376,7 +389,7 @@ class pin_layout:
elif left:
return r1_ll.x - r2_ur.x
elif right:
return r2_ll.x - r1.ur.x
return r2_ll.x - r1_ur.x
elif bottom:
return r1_ll.y - r2_ur.y
elif top:
@ -385,9 +398,8 @@ class pin_layout:
# rectangles intersect
return 0
def overlap_length(self, other):
"""
"""
Calculate the intersection segment and determine its length
"""
@ -399,21 +411,21 @@ class pin_layout:
intersections = self.compute_overlap_segment(other)
# This is the common case where two pairs of edges overlap
# at two points, so just find the distance between those two points
if len(intersections)==2:
(p1,p2) = intersections
return math.sqrt(pow(p1[0]-p2[0],2) + pow(p1[1]-p2[1],2))
if len(intersections) == 2:
(p1, p2) = intersections
return math.sqrt(pow(p1[0]-p2[0], 2) + pow(p1[1]-p2[1], 2))
else:
# This is where we had a corner intersection or none
return 0
def compute_overlap_segment(self, other):
"""
Calculate the intersection segment of two rectangles
"""
Calculate the intersection segment of two rectangles
(if any)
"""
(r1_ll,r1_ur) = self.rect
(r2_ll,r2_ur) = other.rect
(r1_ll, r1_ur) = self.rect
(r2_ll, r2_ur) = other.rect
# The other corners besides ll and ur
r1_ul = vector(r1_ll.x, r1_ur.y)
@ -422,6 +434,7 @@ class pin_layout:
r2_lr = vector(r2_ur.x, r2_ll.y)
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
@ -431,14 +444,14 @@ class pin_layout:
# R1 edges CW
r1_cw_points = [r1_ll, r1_ul, r1_ur, r1_lr, r1_ll]
r1_edges = []
for (p,q) in pairwise(r1_cw_points):
r1_edges.append([p,q])
for (p, q) in pairwise(r1_cw_points):
r1_edges.append([p, q])
# R2 edges CW
r2_cw_points = [r2_ll, r2_ul, r2_ur, r2_lr, r2_ll]
r2_edges = []
for (p,q) in pairwise(r2_cw_points):
r2_edges.append([p,q])
for (p, q) in pairwise(r2_cw_points):
r2_edges.append([p, q])
# There are 4 edges on each rectangle
# so just brute force check intersection of each
@ -460,18 +473,18 @@ class pin_layout:
q.x >= min(p.x, r.x) and \
q.y <= max(p.y, r.y) and \
q.y >= min(p.y, r.y):
return True
return True
return False
def segment_intersection(self, s1, s2):
"""
"""
Determine the intersection point of two segments
Return the a segment if they overlap.
Return None if they don't.
"""
(a,b) = s1
(c,d) = s2
(a, b) = s1
(c, d) = s2
# Line AB represented as a1x + b1y = c1
a1 = b.y - a.y
b1 = a.x - b.x
@ -484,11 +497,11 @@ class pin_layout:
determinant = a1*b2 - a2*b1
if determinant!=0:
if determinant != 0:
x = (b2*c1 - b1*c2)/determinant
y = (a1*c2 - a2*c1)/determinant
r = vector(x,y).snap_to_grid()
r = vector(x, y).snap_to_grid()
if self.on_segment(a, r, b) and self.on_segment(c, r, d):
return r