Make default no magnification to text. PEP8 Cleanup

This commit is contained in:
mrg 2020-12-09 11:42:28 -08:00
parent 9717794400
commit 0a9a946cd1
3 changed files with 101 additions and 70 deletions

View File

@ -1,4 +1,4 @@
import math
class GdsStructure: class GdsStructure:
"""Class represent a GDS Structure Object""" """Class represent a GDS Structure Object"""
@ -15,6 +15,7 @@ class GdsStructure:
self.nodes=[] self.nodes=[]
self.boxes=[] self.boxes=[]
class GdsBoundary: class GdsBoundary:
"""Class represent a GDS Boundary Object""" """Class represent a GDS Boundary Object"""
def __init__(self): def __init__(self):
@ -24,6 +25,7 @@ class GdsBoundary:
self.purposeLayer=0 self.purposeLayer=0
self.coordinates="" self.coordinates=""
class GdsPath: class GdsPath:
"""Class represent a GDS Path Object""" """Class represent a GDS Path Object"""
def __init__(self): def __init__(self):
@ -112,6 +114,7 @@ class GdsPath:
lastY = y lastY = y
return boundaryEquivalent return boundaryEquivalent
class GdsSref: class GdsSref:
"""Class represent a GDS structure reference Object""" """Class represent a GDS structure reference Object"""
def __init__(self): def __init__(self):
@ -123,6 +126,7 @@ class GdsSref:
self.rotateAngle="" self.rotateAngle=""
self.coordinates="" self.coordinates=""
class GdsAref: class GdsAref:
"""Class represent a GDS array reference Object""" """Class represent a GDS array reference Object"""
def __init__(self): def __init__(self):
@ -134,6 +138,7 @@ class GdsAref:
self.rotateAngle="" self.rotateAngle=""
self.coordinates="" self.coordinates=""
class GdsText: class GdsText:
"""Class represent a GDS text Object""" """Class represent a GDS text Object"""
def __init__(self): def __init__(self):
@ -150,6 +155,7 @@ class GdsText:
self.coordinates="" self.coordinates=""
self.textString = "" self.textString = ""
class GdsNode: class GdsNode:
"""Class represent a GDS Node Object""" """Class represent a GDS Node Object"""
def __init__(self): def __init__(self):
@ -159,6 +165,7 @@ class GdsNode:
self.nodeType="" self.nodeType=""
self.coordinates="" self.coordinates=""
class GdsBox: class GdsBox:
"""Class represent a GDS Box Object""" """Class represent a GDS Box Object"""
def __init__(self): def __init__(self):

View File

@ -1,26 +1,25 @@
from .gdsPrimitives import * from .gdsPrimitives import *
from datetime import * from datetime import *
#from mpmath import matrix
#from numpy import matrix
import numpy as np import numpy as np
#import gdsPrimitives import math
import debug import debug
class VlsiLayout: class VlsiLayout:
"""Class represent a hierarchical layout""" """Class represent a hierarchical layout"""
def __init__(self, name=None, units=(0.001,1e-9), libraryName = "DEFAULT.DB", gdsVersion=5): def __init__(self, name=None, units=(0.001,1e-9), libraryName="DEFAULT.DB", gdsVersion=5):
#keep a list of all the structures in this layout # keep a list of all the structures in this layout
self.units = units self.units = units
#print(units) # print(units)
modDate = datetime.now() modDate = datetime.now()
self.structures=dict() self.structures=dict()
self.layerNumbersInUse = [] self.layerNumbersInUse = []
self.debug = False self.debug = False
if name: if name:
#take the root structure and copy it to a new structure with the new name # take the root structure and copy it to a new structure with the new name
self.rootStructureName=self.padText(name) self.rootStructureName=self.padText(name)
#create the ROOT structure # create the ROOT structure
self.structures[self.rootStructureName] = GdsStructure() self.structures[self.rootStructureName] = GdsStructure()
self.structures[self.rootStructureName].name = name self.structures[self.rootStructureName].name = name
self.structures[self.rootStructureName].createDate = (modDate.year, self.structures[self.rootStructureName].createDate = (modDate.year,
@ -36,7 +35,7 @@ class VlsiLayout:
modDate.minute, modDate.minute,
modDate.second) modDate.second)
self.info = dict() #information gathered from the GDSII header self.info = dict() # information gathered from the GDSII header
self.info['units']=self.units self.info['units']=self.units
self.info['dates']=(modDate.year, self.info['dates']=(modDate.year,
modDate.month, modDate.month,
@ -53,12 +52,13 @@ class VlsiLayout:
self.info['libraryName']=libraryName self.info['libraryName']=libraryName
self.info['gdsVersion']=gdsVersion self.info['gdsVersion']=gdsVersion
self.xyTree = [] #This will contain a list of all structure names # This will contain a list of all structure names
#expanded to include srefs / arefs separately. # expanded to include srefs / arefs separately.
#each structure will have an X,Y,offset, and rotate associated # each structure will have an X,Y,offset, and rotate associated
#with it. Populate via traverseTheHierarchy method. # with it. Populate via traverseTheHierarchy method.
self.xyTree = []
#temp variables used in delegate functions # temp variables used in delegate functions
self.tempCoordinates=None self.tempCoordinates=None
self.tempPassFail = True self.tempPassFail = True
@ -68,12 +68,12 @@ class VlsiLayout:
self.pins = {} self.pins = {}
def rotatedCoordinates(self,coordinatesToRotate,rotateAngle): def rotatedCoordinates(self,coordinatesToRotate,rotateAngle):
#helper method to rotate a list of coordinates # helper method to rotate a list of coordinates
angle=math.radians(float(0)) angle=math.radians(float(0))
if(rotateAngle): if(rotateAngle):
angle = math.radians(float(rotateAngle)) angle = math.radians(float(rotateAngle))
coordinatesRotate = [] #this will hold the rotated values coordinatesRotate = [] # this will hold the rotated values
for coordinate in coordinatesToRotate: for coordinate in coordinatesToRotate:
# This is the CCW rotation matrix # This is the CCW rotation matrix
newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle) newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle)
@ -82,53 +82,51 @@ class VlsiLayout:
return coordinatesRotate return coordinatesRotate
def rename(self,newName): def rename(self,newName):
#take the root structure and copy it to a new structure with the new name # take the root structure and copy it to a new structure with the new name
self.structures[newName] = self.structures[self.rootStructureName] self.structures[newName] = self.structures[self.rootStructureName]
self.structures[newName].name = self.padText(newName) self.structures[newName].name = self.padText(newName)
#and delete the old root # and delete the old root
del self.structures[self.rootStructureName] del self.structures[self.rootStructureName]
self.rootStructureName = newName self.rootStructureName = newName
#repopulate the 2d map so drawing occurs correctly # repopulate the 2d map so drawing occurs correctly
del self.xyTree[:] del self.xyTree[:]
self.populateCoordinateMap() self.populateCoordinateMap()
def newLayout(self,newName): def newLayout(self,newName):
#if (newName == "" | newName == 0): # if (newName == "" | newName == 0):
# print("ERROR: vlsiLayout.py:newLayout newName is null") # print("ERROR: vlsiLayout.py:newLayout newName is null")
#make sure the newName is a multiple of 2 characters # make sure the newName is a multiple of 2 characters
#if(len(newName)%2 == 1): # if(len(newName)%2 == 1):
#pad with a zero # pad with a zero
#newName = newName + '\x00' # newName = newName + '\x00'
#take the root structure and copy it to a new structure with the new name # take the root structure and copy it to a new structure with the new name
#self.structures[newName] = self.structures[self.rootStructureName] # self.structures[newName] = self.structures[self.rootStructureName]
modDate = datetime.now() modDate = datetime.now()
self.structures[newName] = GdsStructure() self.structures[newName] = GdsStructure()
self.structures[newName].name = newName self.structures[newName].name = newName
self.rootStructureName = newName self.rootStructureName = newName
self.rootStructureName=newName self.rootStructureName=newName
#create the ROOT structure # create the ROOT structure
self.structures[self.rootStructureName] = GdsStructure() self.structures[self.rootStructureName] = GdsStructure()
#self.structures[self.rootStructureName].name = name # self.structures[self.rootStructureName].name = name
self.structures[self.rootStructureName].createDate = (modDate.year, self.structures[self.rootStructureName].createDate = (modDate.year,
modDate.month, modDate.month,
modDate.day, modDate.day,
modDate.hour, modDate.hour,
modDate.minute, modDate.minute,
modDate.second) modDate.second)
self.structures[self.rootStructureName].modDate = (modDate.year, self.structures[self.rootStructureName].modDate = (modDate.year,
modDate.month, modDate.month,
modDate.day, modDate.day,
modDate.hour, modDate.hour,
modDate.minute, modDate.minute,
modDate.second) modDate.second)
#repopulate the 2d map so drawing occurs correctly #repopulate the 2d map so drawing occurs correctly
@ -155,47 +153,50 @@ class VlsiLayout:
debug.check(len(structureNames)==1,"Multiple possible root structures in the layout: {}".format(str(structureNames))) debug.check(len(structureNames)==1,"Multiple possible root structures in the layout: {}".format(str(structureNames)))
self.rootStructureName = structureNames[0] self.rootStructureName = structureNames[0]
def traverseTheHierarchy(self, startingStructureName=None, delegateFunction=None,
def traverseTheHierarchy(self, startingStructureName=None, delegateFunction = None, transformPath=[], rotateAngle=0, transFlags=[0, 0, 0], coordinates=(0, 0)):
transformPath = [], rotateAngle = 0, transFlags = [0,0,0], coordinates = (0,0)): # since this is a recursive function, must deal with the default
#since this is a recursive function, must deal with the default # parameters explicitly
#parameters explicitly
if startingStructureName == None: if startingStructureName == None:
startingStructureName = self.rootStructureName startingStructureName = self.rootStructureName
#set up the rotation matrix # set up the rotation matrix
if(rotateAngle == None or rotateAngle == ""): if(rotateAngle == None or rotateAngle == ""):
angle = 0 angle = 0
else: else:
# MRG: Added negative to make CCW rotate 8/29/18 # MRG: Added negative to make CCW rotate 8/29/18
angle = math.radians(float(rotateAngle)) angle = math.radians(float(rotateAngle))
mRotate = np.array([[math.cos(angle),-math.sin(angle),0.0], mRotate = np.array([[math.cos(angle), -math.sin(angle), 0.0],
[math.sin(angle),math.cos(angle),0.0], [math.sin(angle), math.cos(angle), 0.0],
[0.0,0.0,1.0]]) [0.0, 0.0, 1.0]])
#set up the translation matrix # set up the translation matrix
translateX = float(coordinates[0]) translateX = float(coordinates[0])
translateY = float(coordinates[1]) translateY = float(coordinates[1])
mTranslate = np.array([[1.0,0.0,translateX],[0.0,1.0,translateY],[0.0,0.0,1.0]]) mTranslate = np.array([[1.0, 0.0, translateX],
#set up the scale matrix (handles mirror X) [0.0, 1.0, translateY],
[0.0, 0.0, 1.0]])
# set up the scale matrix (handles mirror X)
scaleX = 1.0 scaleX = 1.0
if(transFlags[0]): if (transFlags[0]):
scaleY = -1.0 scaleY = -1.0
else: else:
scaleY = 1.0 scaleY = 1.0
mScale = np.array([[scaleX,0.0,0.0],[0.0,scaleY,0.0],[0.0,0.0,1.0]]) mScale = np.array([[scaleX, 0.0, 0.0],
#we need to keep track of all transforms in the hierarchy [0.0, scaleY, 0.0],
#when we add an element to the xy tree, we apply all transforms from the bottom up [0.0, 0.0, 1.0]])
# we need to keep track of all transforms in the hierarchy
# when we add an element to the xy tree, we apply all transforms from the bottom up
transformPath.append((mRotate,mScale,mTranslate)) transformPath.append((mRotate,mScale,mTranslate))
if delegateFunction != None: if delegateFunction != None:
delegateFunction(startingStructureName, transformPath) delegateFunction(startingStructureName, transformPath)
#starting with a particular structure, we will recursively traverse the tree # starting with a particular structure, we will recursively traverse the tree
#********might have to set the recursion level deeper for big layouts! # ********might have to set the recursion level deeper for big layouts!
try: try:
if(len(self.structures[startingStructureName].srefs)>0): #does this structure reference any others? if(len(self.structures[startingStructureName].srefs)>0): #does this structure reference any others?
#if so, go through each and call this function again # if so, go through each and call this function again
#if not, return back to the caller (caller can be this function) # if not, return back to the caller (caller can be this function)
for sref in self.structures[startingStructureName].srefs: for sref in self.structures[startingStructureName].srefs:
#here, we are going to modify the sref coordinates based on the parent objects rotation # here, we are going to modify the sref coordinates based on the parent objects rotation
self.traverseTheHierarchy(startingStructureName = sref.sName, self.traverseTheHierarchy(startingStructureName = sref.sName,
delegateFunction = delegateFunction, delegateFunction = delegateFunction,
transformPath = transformPath, transformPath = transformPath,
@ -205,8 +206,8 @@ class VlsiLayout:
except KeyError: except KeyError:
debug.error("Could not find structure {} in GDS file.".format(startingStructureName),-1) debug.error("Could not find structure {} in GDS file.".format(startingStructureName),-1)
#MUST HANDLE AREFs HERE AS WELL # MUST HANDLE AREFs HERE AS WELL
#when we return, drop the last transform from the transformPath # when we return, drop the last transform from the transformPath
del transformPath[-1] del transformPath[-1]
return return
@ -218,7 +219,6 @@ class VlsiLayout:
for layerNumber in self.layerNumbersInUse: for layerNumber in self.layerNumbersInUse:
self.processLabelPins((layerNumber, None)) self.processLabelPins((layerNumber, None))
def populateCoordinateMap(self): def populateCoordinateMap(self):
def addToXyTree(startingStructureName = None,transformPath = None): def addToXyTree(startingStructureName = None,transformPath = None):
uVector = np.array([[1.0],[0.0],[0.0]]) #start with normal basis vectors uVector = np.array([[1.0],[0.0],[0.0]]) #start with normal basis vectors
@ -281,8 +281,6 @@ class VlsiLayout:
self.newLayout(newRoot) self.newLayout(newRoot)
self.rootStructureName = newRoot self.rootStructureName = newRoot
def addInstance(self,layoutToAdd,nameOfLayout=0,offsetInMicrons=(0,0),mirror=None,rotate=None): def addInstance(self,layoutToAdd,nameOfLayout=0,offsetInMicrons=(0,0),mirror=None,rotate=None):
""" """
Method to insert one layout into another at a particular offset. Method to insert one layout into another at a particular offset.
@ -406,7 +404,7 @@ class VlsiLayout:
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].paths.append(pathToAdd) self.structures[self.rootStructureName].paths.append(pathToAdd)
def addText(self, text, layerNumber=0, purposeNumber=0, offsetInMicrons=(0,0), magnification=0.1, rotate = None): def addText(self, text, layerNumber=0, purposeNumber=0, offsetInMicrons=(0,0), magnification=None, rotate=None):
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1])) offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
textToAdd = GdsText() textToAdd = GdsText()
textToAdd.drawingLayer = layerNumber textToAdd.drawingLayer = layerNumber
@ -415,7 +413,8 @@ class VlsiLayout:
textToAdd.transFlags = [0,0,0] textToAdd.transFlags = [0,0,0]
textToAdd.textString = self.padText(text) textToAdd.textString = self.padText(text)
#textToAdd.transFlags[1] = 1 #textToAdd.transFlags[1] = 1
textToAdd.magFactor = magnification if magnification:
textToAdd.magFactor = magnification
if rotate: if rotate:
#textToAdd.transFlags[2] = 1 #textToAdd.transFlags[2] = 1
textToAdd.rotateAngle = rotate textToAdd.rotateAngle = rotate

25
compiler/processGDS.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env python3
import sys
from gdsMill import gdsMill
if len(sys.argv) < 2:
print("Usage: {0} in.gds out.gds".format(sys.argv[0]))
sys.exit(1)
in_gds_file = sys.argv[1]
out_gds_file = sys.argv[2]
layout = gdsMill.VlsiLayout()
reader = gdsMill.Gds2reader(layout)
reader.loadFromFile(in_gds_file)
struct = layout.structures[layout.rootStructureName]
# Do something to the structure
for text in struct.texts:
print(text.textString)
text.magFactor=""
writer = gdsMill.Gds2writer(layout)
writer.writeToFile(out_gds_file)