Convert many box objects to circles efficiently

edited January 2023 in Python scripting

I have 360,000 boxes and I need to turn them all into circles. I'm not 100% sure what size the boxes will be but maybe I can get that info another way?

Right now This loop works but it can only convert about 417 boxes per second and that is 12 minutes for a file. Is there any way to do this in bulk faster?

some thoughts:
Somehow get info on all the boxes in bulk, so I dont dynamically generate a circle for each one.
reduce number of points in circle?
get all of the box coordinates from an external file and simply draw them in myself as circles with some bulk function?
is there a bulk draw in function?

Thanks!

  dbu_factor = layout.dbu
  #make a single circle
  def make_cir(r):        
    radius = r/2
    nr_points = 32
    angles = np.linspace(0,2*np.pi,nr_points+1)[0:-1]
    points = []
    for ind,angle in enumerate(angles):
      points.append(pya.DPoint(radius*np.cos(angle),radius*np.sin(angle)))
    circle = pya.DSimplePolygon(points)
    return circle

  #Get the boxes
  imported_cell_shapes3 = []
  start_time = time.time()
  for idx,f in enumerate(imported_cell.shapes(layout.layer(1,0))):
    #imported_cell_shapes3.append(f)
    box_center_x,box_center_y = float(f.box_center.x*dbu_factor),float(f.box_center.y*dbu_factor)
    box_width = float(f.box_dwidth)
    box_height = float(f.box_dheight)
    biggest_box_dim = max(box_width,box_height)
    temp_circle = make_cir(biggest_box_dim)
    imported_cell.shapes(l3).insert(temp_circle.moved(box_center_x,box_center_y))
    #imported_cell_shapes3.append([box_center_x,box_center_y,box_width,box_height])
    f.delete()
    #print(f)
  end_time =time.time()
  print(f"time to replace {idx} squares with circles {end_time-start_time}")

Comments

  • edited January 2023

    Your code looks not bad. However, try how the performance would improve with the following changes using List Comprehensions.

    # https://www.klayout.de/forum/discussion/2227/convert-many-box-objects-to-circles-efficiently
    #
    import numpy as np
    import pya
    
    def make_cir(r):
      radius = r/2
      nr_points = 32
      angles = np.linspace(0,2*np.pi,nr_points+1)[0:-1]
      # "List Comprehensions" must be faster than list.append()
      points = [ pya.DPoint(radius*np.cos(angle),radius*np.sin(angle)) for ind,angle in enumerate(angles) ]
      circle = pya.DSimplePolygon(points)
      return circle
    
    circle = make_cir(10.0)
    print( "# Number of vetices = %d" % circle.num_points() )
    
    # Number of vetices = 32
    
  • If you could sort the boxes (presumably squares, as
    rectangles would want to become ovals?) into "heaps"
    of like geometry, then you'd have to do the circle-
    figuring once per geom instead of once per object.

    If you took each of those squares and substituted a
    geometry-specific instance, which contains the same
    square, you could at the end write a circle over that
    (for each geom-unique) and then flatten-all.

  • @sekigawa Thanks! That's a great idea. I'll try this and report back with performance.

  • @dick_freebird
    Thanks!
    I think I might be able to figure out which squares are going to become what size of circle apriori and in bulk so I don't have to call the circle routine on each one. I'll see what properties are available to evaluate that before entering the klayout portion of my workflow.

  • edited January 2023

    Hello,

    Why not replace them with the "CIRCLE" (or "ELLIPSE") pcell from the "Basic" Library???

    Cheers,

    Tomas

Sign In or Register to comment.