Esempio n. 1
0
    def define_points(self, pts):
        c = Shape(self.original_shape)

        if len(c) == 0:
            return pts

        if self.original_shape.is_closed():
            if not c[0] == c[-1]:
                c.append(c[0])
            #closed curve
            c.append(c[1])
        else:
            # open curve
            pts.append(c[0])

        min_sw = self.stub_width
        for i in range(1, len(c) - 1):
            angle1 = angle_rad(c[i], c[i - 1])
            angle2 = angle_rad(c[i + 1], c[i])
            turn = (angle2 - angle1 + pi) % (2 * pi) - pi
            if turn == 0 or (abs(turn) <=
                             (pi / 2.0) and self.only_sharp_angles):
                pts.append(c[i])
            elif abs(turn == pi):
                LOG.error(
                    "ShapeStub::define_points : ERROR : Cannot stub shape with a 180 degree turn"
                )
            else:
                d1 = distance(c[i], c[i - 1])
                d2 = distance(c[i + 1], c[i])
                L = self.stub_width * sin(turn / 2.0) / sin(turn)
                max_L = max([d1 / 2.0, d2 / 2.0])
                if L > max_L:
                    L = max_L
                    sw = L * sin(turn) / sin(turn / 2.0)
                else:
                    sw = self.stub_width
                if sw < min_sw:
                    min_sw = sw

                s1 = (c[i][0] - L * cos(angle1), c[i][1] - L * sin(angle1))
                s2 = (c[i][0] + L * cos(angle2), c[i][1] + L * sin(angle2))
                pts.append(s1)
                pts.append(s2)
        ''' REFACTORED --> moved to constructor
        if self.original_shape.closed:
            #closed curve
            self.close()
        else:
        '''
        if not self.original_shape.closed:  # open curve
            pts.append(c[-1])

        if min_sw < self.stub_width:
            LOG.warning(
                "Warning: ShapeStub::define_points : Stub width is reduced from "
                + str(self.stub_width) + " to " + str(min_sw) +
                "to stub shape.")

        return pts
Esempio n. 2
0
 def __filter_str__(self, item):
     if item is None:
         return None
     name = copy.copy(item)
     name = name.replace("-", "_")
     name = name.replace(" ", "_")
     name = name.replace(".", "_")
     name = name.replace("/", "_")
     if self.scramble_all:
         hashval = hash(name)
         if hashval < 0:
             prefix = "S_"
         else:
             prefix = "S"
         name = prefix + str(abs(hashval))
         name = name.upper()
     elif self.max_name_length != None:
         if self.max_name_length > 0 and len(name) > self.max_name_length:
             hashval = str(abs(hash(name)))
             L = len(hashval)
             if L > self.max_name_length + 1:
                 raise ValueError(
                     "max_name_length %d in NameScrambleFilter is too short for hash algorithm"
                     % (self.max_name_length))
             name = name[0:self.max_name_length - L - 1] + "_" + hashval
             LOG.warning("Too long name encountered. Current length = %d" %
                         len(name))
     return [name]
Esempio n. 3
0
 def __radii_and_turns__(self, s):
     R = self.radii
     r = array(R)
     D = s.distances()
     a2 = s.angles_rad()  # angle to next vertex
     a1 = roll(a2, 1)  # angle from previous vertex
     t = (a2 - a1 +
          pi) % (2 * pi) - pi  # turns, save an extra angle computation
     tt = abs(tan(0.5 * t))
     L = R * tt  # length of the straight section consumed by the bend
     (Swsa, dummy) = self.__original_shape_without_straight_angles__(
         self.original_shape, self.radii)
     if not Swsa.closed:
         L[0] = 0
         L[-1] = 0
     # check where the bend consumes more length than possible!
     m_L = ((L + roll(L, -1)) - D)  # missing length in the next segment
     missing_L = amax(column_stack((m_L, roll(m_L, 1))),
                      1)  # missing length over previous and next segment
     overf = (missing_L > 0.5 / settings.get_grids_per_unit())
     r[overf] = 0.5 * (amin(column_stack(
         (D[overf], roll(D, 1)[overf])), 1)) / tt[overf]
     # FIXME: Find a more robust algorithm to reduce the radius if there is insufficient space
     r_difference = R - r
     if (r_difference >
             settings.get_current_library().units_per_grid).any():
         LOG.warning(
             "Bend radius is reduced by maximum %f to round shape." %
             max(r_difference))
     if not Swsa.closed:
         r[0] = 0
         r[-1] = 0
     L = r * tt  # recompute the length of the straight section consumed by the bend
     return (r, tt, t, a1, a2, L, D)
Esempio n. 4
0
 def define_gdsiilayer_map(self):
     lm = {}
     for k, v in self.pplayer_map.items():
         if v in lm:
             LOG.warning(
                 "PPLayer to GDSII layer mapping for GDSII %i:%i => %s:%s overwritten with %s:%s"
                 % (v[0], v[1], lm[v][0], lm[v][1], k[0], k[1]))
         lm[v] = k
     return lm
Esempio n. 5
0
 def __getitem__(self, gdsiilayer, default=None):
     if (gdsiilayer.number, gdsiilayer.datatype) in self.layer_map:
         return self.layer_map[(gdsiilayer.number, gdsiilayer.datatype)]
     else:
         error_message = "Warning during GDSII import : no corresponding process/purpose layer found for number = %i and datatype = %s" % (
             gdsiilayer.number, gdsiilayer.datatype)
         if self.ignore_undefined_mappings:
             LOG.warning(error_message)
             return default
         else:
             raise Exception(error_message)
Esempio n. 6
0
 def __getitem__(self, key, default=None):
     if (key.number, key.datatype) in self.gdsiilayer_map:
         (pl, pp) = self.gdsiilayer_map[(key.number, key.datatype)]
         return PPLayer(process=pl, purpose=pp)
     else:
         error_message = "Warning during GDSII import : no corresponding process/purpose layer found for number = %i and datatype = %s" % (
             key.number, key.datatype)
         if self.ignore_undefined_mappings:
             LOG.warning(error_message)
             return default
         else:
             raise Exception(error_message)
Esempio n. 7
0
 def __getitem__(self, key, default=None):
     if (key.process, key.purpose) in self.pplayer_map:
         (lay, dat) = self.pplayer_map[(key.process, key.purpose)]
         return GdsiiLayer(number=lay, datatype=dat)
     else:
         error_message = "Warning during GDSII export : no corresponding GDSII layer/datatype found for process = %s and purpose = %s" % (
             key.process, key.purpose)
         if self.ignore_undefined_mappings:
             LOG.warning(error_message)
             return default
         else:
             raise Exception(error_message)
Esempio n. 8
0
 def shapes_character (self, character, letter_height = 1.0, south_west_coord = (0.0,0.0), angle = 0.0):
     #returns a list of shapes!!!
     if character in self.coords:
         shapes = self.coords[character]
     else:
         shapes = [self.default_char]
     ret_shapes = []
     #T = Rotation((0.0,0.0), angle) + Magnification((0.0,0,0), letter_height) + Translation(south_west_coord)
     T = NoDistortTransform(south_west_coord, angle, letter_height/self.letter_height())
     for s in shapes:
         if len(s) < 2:
             LOG.warning("Shape with too few coordinates in letter " % character)
         #ret_shapes.append(shape_translate(shape_scale(shape_rotate(s, (0.0,0.0), angle), (letter_height, letter_height)), south_west_coord))		
         ret_shapes.append(T.apply_to_copy(s))
     return ret_shapes
Esempio n. 9
0
 def top_layout(self):
     L = self.unreferenced_structures()
     if len(L) == 1:
         return L[0]
     elif len(L) == 0:
         if len(self.structures) == 0:
             return Structure("__empty__")
         else:
             LOG.warning("There is no top_level structure in library %s. This could be caused by a circular reference" % self.name)
             return None
     elif self.layout:
         warning_string = """There is more than one top-level structure in library %s. 
                             This is ambiguous if the library is to be used as a layout.
                             Please make sure that all but the top-level structures are referred to.
                             #The following structures are 'floating': 
                             #%s """ % (self.name, "#\n".join([s.name for s in L]))
         LOG.warning(warning_string)
Esempio n. 10
0
    def collect_Path(self, item, additional_transform=None, **kwargs):
        shape = item.shape.transform_copy(item.transformation +
                                          additional_transform)
        shape.snap_to_grid(self.grids_per_unit)
        shape.remove_identicals()
        coordinates = Shape(shape)

        if len(coordinates) < 2:
            if self.write_empty:
                LOG.warning("PATH with fewer than 2 coordinates not allowed")
            return

        if shape.closed:
            if not (shape[-1] == shape[0]): coordinates.append(shape[0])

        self.collect_path_element(layer=item.layer,
                                  coordinates=coordinates,
                                  line_width=item.line_width,
                                  path_type=item.path_type)
        return
Esempio n. 11
0
 def collect_Boundary(self, item, additional_transform=None, **kwargs):
     shape = item.shape.transform_copy(item.transformation +
                                       additional_transform)
     shape.snap_to_grid(self.grids_per_unit)
     shape.remove_identicals()
     coordinates = shape
     # BOUNDARIES
     if len(shape) < 3:
         LOG.warning(
             "BOUNDARY with fewer than 3 coordinates not allowed in structure %s"
             % self.__current_structure__.name)
         return
     if len(shape) > TECH.GDSII.MAX_VERTEX_COUNT:
         LOG.warning("BOUNDARY with more than " +
                     str(TECH.GDSII.MAX_VERTEX_COUNT) +
                     " coordinates not supported in structure " +
                     self.__current_structure__.name)
     # shape must be closed!
     if not (coordinates[0] == coordinates[-1]):
         coordinates.append(coordinates[0])
     self.collect_boundary_element(layer=item.layer,
                                   coordinates=coordinates)
     return
Esempio n. 12
0
    def define_points(self, pts):
        c = Shape(self.original_shape)
        if len(c) == 0:
            return

        if self.original_shape.is_closed():
            if not c[0] == c[-1]:
                c.append(c[0])
            #closed curve
            c.append(c[1])
        else:
            # open curve
            pts.append(c[0])

        c.remove_identicals()

        min_sw = self.stub_width
        for i in range(1, len(c) - 1):
            angle1 = angle_rad(c[i], c[i - 1])
            angle2 = angle_rad(c[i + 1], c[i])
            turn = (angle2 - angle1 + pi) % (2 * pi) - pi
            if turn == 0 or (abs(turn) <=
                             (pi / 2.0) and self.only_sharp_angles):
                pts.append(c[i])
            elif abs(turn == pi):
                LOG.error("Cannot stub shape with a 180 degree turn")
            else:
                d1 = distance(c[i], c[i - 1])
                d2 = distance(c[i + 1], c[i])
                L = self.stub_width * sin(turn / 2.0) / sin(turn)
                max_L = max([d1 / 2.0, d2 / 2.0])
                if L > max_L:
                    L = max_L
                    sw = L * sin(turn) / sin(turn / 2.0)
                else:
                    sw = self.stub_width
                if sw < min_sw:
                    min_sw = sw

                theta_div2 = (pi - angle1 + angle2) % (2 * pi) / 2.0

                s1 = Coord2(c[i][0] - L * cos(angle1),
                            c[i][1] - L * sin(angle1))
                s2 = (c[i][0] + L * cos(angle2), c[i][1] + L * sin(angle2))

                B = -self.stub_height * sign(turn)
                delta = 0.5 * (self.stub_width - self.tip_width)
                s2 = (s1[0] + B * cos(angle1 + theta_div2) +
                      delta * cos(angle1 + theta_div2 - pi / 2.0),
                      s1[1] + B * sin(angle1 + theta_div2) +
                      delta * sin(angle1 + theta_div2 - pi / 2.0))
                s4 = Coord2(c[i][0] + L * cos(angle2),
                            c[i][1] + L * sin(angle2))
                s3 = (s4[0] + B * cos(angle2 + pi - theta_div2) +
                      delta * cos(angle2 + pi - theta_div2 + pi / 2.0),
                      s4[1] + B * sin(angle2 + pi - theta_div2) +
                      delta * sin(angle2 + pi - theta_div2 + pi / 2.0))
                pts.append(s1)
                pts.append(s2)
                pts.append(s3)
                pts.append(s4)

        if not self.original_shape.closed:
            # open curve
            pts.append(c[-1])

        if min_sw < self.stub_width:
            LOG.warning("Stub width is reduced from " + str(self.stub_width) +
                        " to " + str(min_sw) + "to stub shape.")

        return pts
Esempio n. 13
0
    def define_points(self, pts):

        (s, R, A) = self.__original_shape_without_straight_angles__()

        if len(R) != len(s):
            raise AttributeError(
                "ShapeRoundAdiabaticSplineGeneric: length of radius vector should be identical to that of points in shape"
            )
        if len(A) != len(s):
            raise AttributeError(
                "ShapeRoundAdiabaticSplineGeneric: length of adiabatic_angles vector should be identical to that of points in shape"
            )

        if len(s) < 3:
            self.__points__ = s.points
            return
        margin = 0.5 / get_grids_per_unit()

        S = []

        if not self.original_shape.closed:
            S.append(numpy.array([s.points[0]]))
        L1 = 0.0

        for i in range(1, len(s) - 1):
            sh = AdiabaticSplineCircleSplineShape(start_point=s[i - 1],
                                                  turn_point=s[i],
                                                  end_point=s[i + 1],
                                                  radius=R[i],
                                                  adiabatic_angles=A[i],
                                                  angle_step=self.angle_step)
            L0 = sh[0].distance(s[i])
            if L0 + L1 - margin > s[i - 1].distance(s[i]):
                LOG.warning(
                    "Insufficient space for spline rounding in (%f, %f)" %
                    (s[i].x, s[i].y))
            L1 = sh[-1].distance(s[i])
            S.append(sh.points)

        if self.original_shape.closed:
            sh = AdiabaticSplineCircleSplineShape(start_point=s[-2],
                                                  turn_point=s[-1],
                                                  end_point=s[0],
                                                  radius=R[-1],
                                                  adiabatic_angles=A[-1],
                                                  angle_step=self.angle_step)
            L0 = sh[0].distance(s[-1])
            if L0 + L1 - margin > s[-2].distance(s[-1]):
                LOG.warning(
                    "Insufficient space for spline rounding in (%f, %f)" %
                    (s[-1].x, s[-1].y))
            L1 = sh[-1].distance(s[-1])
            S.append(sh.points)
            sh = AdiabaticSplineCircleSplineShape(start_point=s[-1],
                                                  turn_point=s[0],
                                                  end_point=s[1],
                                                  radius=R[0],
                                                  adiabatic_angles=A[0],
                                                  angle_step=self.angle_step)
            L0 = sh[0].distance(s[0])
            if L0 + L1 - margin > s[-1].distance(s[0]):
                LOG.warning(
                    "Insufficient space for spline rounding in (%f, %f)" %
                    (s[0].x, s[0].y))
            L1 = sh[-1].distance(s[0])
            S.append(sh.points)
            self.__closed__ = True
        else:
            # open curve
            S.append(numpy.array([s.points[-1]]))
            L0 = 0.0
            if L0 + L1 - margin > s[-2].distance(s[-1]):
                LOG.warning(
                    "Insufficient space for spline rounding in (%f, %f)" %
                    (s[-1].x, s[-1].y))
            L1 = sh[-1].distance(s[0])
            self.__closed__ = False
        return numpy.vstack(S)