def print_lib_info(gdslib=CONFIG["gdslib"], dump_file=None): """ cell cell_path md5_hash """ gds_files = list_gds_files(gdslib) if not gds_files: return names = [] filepaths = [] geohashes = [] build_dates = [] for filepath in gds_files: root, name = os.path.split(filepath) name = name[:-4] geohash = pp.load_component(name=name, dirpath=root).hash_geometry() names += [name] filepaths += [str(filepath)] geohashes += [geohash] build_dates += [time.ctime(os.path.getmtime(filepath))] n_name = max([len(x) for x in names]) + 1 n_path = max([len(x) for x in filepaths]) + 1 n_geohash = max([len(x) for x in geohashes]) + 1 n_build_date = max([len(x) for x in build_dates]) + 1 lines = [] line = ("name".ljust(n_name) + "path".ljust(n_path) + "hash geometry".ljust(n_geohash) + "build date".ljust(n_build_date) ) # +'md5 hash'.ljust(n_hash) lines += [line] lines += ["-" * len(line)] for name, path, geohash, build_date in zip(names, filepaths, geohashes, build_dates): line = "{}{}{}{}".format( name.ljust(n_name), path.ljust(n_path), geohash.ljust(n_geohash), build_date.ljust(n_build_date), ) lines += [line] assert not dump_file.endswith(".gds") if dump_file is None: print() for line in lines: print(line) print() elif type(dump_file) == str: with open(dump_file, "w") as fw: for line in lines: fw.write(line + "\n") elif hasattr(dump_file, "write"): for line in lines: dump_file.write(line + "\n") else: raise ValueError("invalid filepath, {}".format(dump_file))
def compare_component_hash( component_type, component_type2factory=component_type2factory, path_library=CONFIG["gdslib"], path_test=CONFIG["gdslib_test"], ): """ raises Exception if component has changed from the library writes component if it does not exist Args: component_type: path_library: path_test: """ component_new = lock_component( component_type, component_type2factory=component_type2factory, path_library=path_test, ) component_new.name += "_new" gdspath_new = path_test / (component_type + ".gds") gdspath_library = path_library / (component_type + ".gds") if not os.path.isfile(gdspath_library): lock_component( component_type=component_type, component_type2factory=component_type2factory, path_library=path_library, ) print(f"writing new component {component_type} into {path_library}") return component_library = pp.load_component(component_name=component_type, component_path=path_library) component_library.name += "_lib" gdshash_new = gdspy.gdsii_hash(gdspath_new) gdshash_library = gdspy.gdsii_hash(gdspath_library) # gdshash_new = component_library.hash_geometry() # gdshash_library = component_new.hash_geometry() same_hash = gdshash_new == gdshash_library if not same_hash: error_hash = f"`{component_library}` hash(GDS) {gdspath_new} differs from the library {gdspath_library}, showing both cells in Klayout \n" error_settings = f"different settings: {diff(component_library.get_settings(), component_new.get_settings())}" c = pp.Component(name=component_type) c << component_new c << component_library pp.show(c) print(error_hash + error_settings) return same_hash
def load_library(gdslib=CONFIG["gdslib"], tech=conf.tech.name): """ Load a cell library from the tech """ lib = {} gds_files = list_gds_files(gdslib, tech) for filepath in gds_files: filename = filepath.stem lib[filename] = pp.load_component(name=filename, dirpath=filepath.parent, with_info_labels=False) return lib
def is_same_as_in_library( component, tech=CONFIG["tech"], gdspath_tmp=CONFIG["gdslib_test"], ): """ component: a pp.Component tech: the tech where to find a reference component """ # # Check if the component is here # if not component_is_in_library(component, tech): # return False # Library component path lib_component_dir = get_library_path(tech) lib_hash = None lib_component = pp.load_component(component.name, lib_component_dir) lib_hash = lib_component.hash_geometry() new_component_hash = component.hash_geometry() return new_component_hash == lib_hash
def add_component( component, tech, add_ports_to_all_cells=False, with_confirmation=True, force_replace=False, add_port_pins=True, ): """ Arg: component <pp.Component> tech <str> Add a component to a given tech """ lib_component_path = get_component_path(component, tech) # If it is a new library, create the path dirname = os.path.dirname(lib_component_path) if not os.path.exists(dirname): os.makedirs(dirname) # Save component to make sure we have all the port and json files new_component_path = GDS_PATH_TMP / (component.name + ".gds") params = { "add_port_pins": add_port_pins, "add_ports_to_all_cells": add_ports_to_all_cells } write_component(component, new_component_path, **params) # Reload component (to make sure ports info is added etc...) component = pp.load_component(component.name, GDS_PATH_TMP) write_component(component, new_component_path, **params) # If component is not in library, simply add it if not component_is_in_library(component, tech) or force_replace: _copy_component(new_component_path, lib_component_path) # write_component(component, lib_component_path, # add_ports_to_all_cells=add_ports_to_all_cells) return # If it is already there, compare the hash if is_same_as_in_library(component, tech): # We can safely overwrite the component since the geometry has not changed if not hasattr(component, "properties"): component.properties = {} _copy_component(new_component_path, lib_component_path) print("{} cell geometry unchanged (cell/port names may have changed).". format(component.name)) elif with_confirmation: # Show the diff try: gds_diff = gdsdiff(lib_component_path, component) pp.show(gds_diff) a = input( "Do you want to replace {} with new version? [Y/N]".format( component.name)) if a == "Y": _copy_component(new_component_path, lib_component_path) print("Replaced component {} by new one".format( component.name)) else: print("Did not modify the component") except Exception as e: print("Cannot show the diff") print(e) else: _copy_component(new_component_path, lib_component_path) print("Replaced component {} by new one".format(component.name))