Loading CHANGELOG +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - to_feather and from_feather method overwrites to DMT.DataFrame - DutLib save version 1.1: Added back proper load on from different path - optional validate Flag for sim_con.read_and_run() ### Fixed - hidden bug in naming.get_specifier_from_string when a specifier is repeated in a non-convertable string Loading DMT/core/dut_lib.py +32 −20 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ try: except ImportError: pass SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=0) SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=1) class __Filter(object): Loading Loading @@ -542,6 +542,7 @@ class DutLib(object): "wafer": self.wafer, "date_tapeout": self.date_tapeout, "date_received": self.date_received, "save_dir": str(self._save_dir), "__DutLib__": str( SEMVER_DUTLIB_CURRENT ), # make versions, so we can introduce compatibility here!} Loading Loading @@ -579,7 +580,12 @@ class DutLib(object): if (lib_directory / "dut_lib.json").exists(): with (lib_directory / "dut_lib.json").open("r", encoding="utf8") as file_json: json_content = json.load(file_json) if not json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT: if json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT: pass elif json_content["__DutLib__"] == VersionInfo(major=1, minor=0): print("DMT:DutLib:load(): Loading an old lib. This will work, if the machine if the path stays the same. Otherwise, add 'save_dir' key to the dut_lib.json manually.") else: raise IOError("DMT.DutLib: Tried to load a DutLib with unkown version.") for key, value in json_content.items(): Loading Loading @@ -610,6 +616,11 @@ class DutLib(object): dut_lib.date_tapeout = json_content["date_tapeout"] dut_lib.date_received = json_content["date_received"] try: dut_lib._save_dir = json_content["save_dir"] except KeyError: pass elif (lib_directory / "dut_lib.p").exists(): with (lib_directory / "dut_lib.p").open(mode="rb") as handle: dut_lib = cpickle.load(handle) Loading Loading @@ -645,23 +656,24 @@ class DutLib(object): dut_lib.duts.append(DutView.load_dut(file_dut)) # correct dut paths: if save_dir_old: if dut_lib.dut_ref_dut_dir is not None: dut_lib.dut_ref_dut_dir = Path(dut_lib.dut_ref_dut_dir) if not dut_lib.dut_ref_dut_dir.exists(): dut_lib.dut_ref_dut_dir = Path( str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) if dut_lib.dut_internal_dut_dir is not None: dut_lib.dut_internal_dut_dir = Path(dut_lib.dut_internal_dut_dir) if not dut_lib.dut_internal_dut_dir.exists(): dut_lib.dut_internal_dut_dir = Path( str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) if dut_lib.dut_intrinsic_dut_dir is not None: dut_lib.dut_intrinsic_dut_dir = Path(dut_lib.dut_intrinsic_dut_dir) if not dut_lib.dut_intrinsic_dut_dir.exists(): dut_lib.dut_intrinsic_dut_dir = Path( str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) for dut in dut_lib.duts: Loading DMT/core/dut_view.py +3 −1 Original line number Diff line number Diff line Loading @@ -742,6 +742,7 @@ class DutView(object): data: Union[DataFrame, Sweep, str, os.Pathlike], key: Union[str, None] = None, force: bool = True, validate: bool = True, **kwargs, ): """Add a measurement or simulation data to the DutView's data. Loading Loading @@ -787,6 +788,7 @@ class DutView(object): self.data[key] = data elif isinstance(data, Sweep): # simulation valid? if not validate: self.validate_simulation_successful(data) # try special import self.import_output_data(data) Loading DMT/core/sim_con.py +23 −18 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ class SimCon(object, metaclass=Singleton): {"dut": dut_a, "sweep": sweep_a} for dut_a, sweep_a in itertools.product(dut, sweep) ] def run_and_read(self, force=False, remove_simulations=False, parallel_read=False): def run_and_read(self, force=False, remove_simulations=False, parallel_read=False, validate=True): """Run all queued simulations and load the results into the Duts' databases. Parameters Loading Loading @@ -195,14 +195,14 @@ class SimCon(object, metaclass=Singleton): if parallel_read: print("Checking which simulations need to be run in parallel:") sims_checked = parallel( delayed(_check_simulation_needed)(i_sim, n_tot, **sim) delayed(_check_simulation_needed)(i_sim, n_tot, validate=validate, **sim) for i_sim, sim in enumerate(self.sim_list) ) else: print("Checking which simulations need to be run:") # parallel not working with VAE modelcard currently since get_circuit is monkey patched sims_checked = [ _check_simulation_needed(i_sim, n_tot, **sim) _check_simulation_needed(i_sim, n_tot, validate=validate, **sim) for i_sim, sim in enumerate(self.sim_list) ] Loading Loading @@ -232,7 +232,7 @@ class SimCon(object, metaclass=Singleton): print("Reading in the results in parallel:") sims_read = parallel( delayed(_read_process_results)( process["success"], process["dut"], process["sweep"] process["success"], process["dut"], process["sweep"], validate=validate ) for process in process_finished ) Loading @@ -240,7 +240,7 @@ class SimCon(object, metaclass=Singleton): print("Reading in the results:") # parallel not working with VAE modelcard currently since get_circuit is monkey patched sims_read = [ _read_process_results(process["success"], process["dut"], process["sweep"]) _read_process_results(process["success"], process["dut"], process["sweep"], validate=validate) for process in process_finished ] all_sim_success = all(sim["success"] for sim in sims_read) Loading Loading @@ -800,7 +800,7 @@ class SimCon(object, metaclass=Singleton): return 0 def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=None): def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, validate=True, sweep_exists=None): """Function to check if the simulation is needed or already present in the database Parameter Loading @@ -821,6 +821,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No print_progress_bar(i_sim, n_tot, prefix="Progress", length=50) try: # was it simulated already successfully ? if validate: dut.validate_simulation_successful(sweep) print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and results are valid, only data needs to be read.", Loading @@ -830,8 +831,12 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No dut_name, sim_name, ) else: print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} not checked for validity.", ) logging.debug("The simulation folder of this simulation was %s", dut.get_sim_folder(sweep)) dut.add_data(sweep) dut.add_data(sweep, validate=validate) except SimulationFail: print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and failed.", Loading @@ -846,7 +851,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No return dut.data def _read_process_results(success, dut, sweep): def _read_process_results(success, dut, sweep, validate=True): """Read the process results Parameter Loading @@ -866,7 +871,7 @@ def _read_process_results(success, dut, sweep): # inform data_manager about the finished simulations try: if success: dut.add_data(sweep) dut.add_data(sweep, validate=validate) logging.info("Simulation of DuT %s with sweep %s successfull.", dut_name, sim_name) else: color_red = "\033[91m" Loading DMT/ngspice/dut_ngspice.py +1 −1 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ class DutNgspice(DutCircuit): str_netlist += ( "set wr_vecnames\n" + f"tran {tau/40} {3*tau}\n" + f"wrdata output_ngspice_tr_{i_row}_{i_tr}.ngspice_tr alli allv\n" + f"wrdata output_ngspice_tr_{i_tr}.ngspice_tr alli allv\n" # TODO one file per ngspice variable "index", how to? + "unset wr_vecnames\n" ) Loading Loading
CHANGELOG +2 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Added - to_feather and from_feather method overwrites to DMT.DataFrame - DutLib save version 1.1: Added back proper load on from different path - optional validate Flag for sim_con.read_and_run() ### Fixed - hidden bug in naming.get_specifier_from_string when a specifier is repeated in a non-convertable string Loading
DMT/core/dut_lib.py +32 −20 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ try: except ImportError: pass SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=0) SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=1) class __Filter(object): Loading Loading @@ -542,6 +542,7 @@ class DutLib(object): "wafer": self.wafer, "date_tapeout": self.date_tapeout, "date_received": self.date_received, "save_dir": str(self._save_dir), "__DutLib__": str( SEMVER_DUTLIB_CURRENT ), # make versions, so we can introduce compatibility here!} Loading Loading @@ -579,7 +580,12 @@ class DutLib(object): if (lib_directory / "dut_lib.json").exists(): with (lib_directory / "dut_lib.json").open("r", encoding="utf8") as file_json: json_content = json.load(file_json) if not json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT: if json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT: pass elif json_content["__DutLib__"] == VersionInfo(major=1, minor=0): print("DMT:DutLib:load(): Loading an old lib. This will work, if the machine if the path stays the same. Otherwise, add 'save_dir' key to the dut_lib.json manually.") else: raise IOError("DMT.DutLib: Tried to load a DutLib with unkown version.") for key, value in json_content.items(): Loading Loading @@ -610,6 +616,11 @@ class DutLib(object): dut_lib.date_tapeout = json_content["date_tapeout"] dut_lib.date_received = json_content["date_received"] try: dut_lib._save_dir = json_content["save_dir"] except KeyError: pass elif (lib_directory / "dut_lib.p").exists(): with (lib_directory / "dut_lib.p").open(mode="rb") as handle: dut_lib = cpickle.load(handle) Loading Loading @@ -645,23 +656,24 @@ class DutLib(object): dut_lib.duts.append(DutView.load_dut(file_dut)) # correct dut paths: if save_dir_old: if dut_lib.dut_ref_dut_dir is not None: dut_lib.dut_ref_dut_dir = Path(dut_lib.dut_ref_dut_dir) if not dut_lib.dut_ref_dut_dir.exists(): dut_lib.dut_ref_dut_dir = Path( str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) if dut_lib.dut_internal_dut_dir is not None: dut_lib.dut_internal_dut_dir = Path(dut_lib.dut_internal_dut_dir) if not dut_lib.dut_internal_dut_dir.exists(): dut_lib.dut_internal_dut_dir = Path( str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) if dut_lib.dut_intrinsic_dut_dir is not None: dut_lib.dut_intrinsic_dut_dir = Path(dut_lib.dut_intrinsic_dut_dir) if not dut_lib.dut_intrinsic_dut_dir.exists(): dut_lib.dut_intrinsic_dut_dir = Path( str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory)) str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory), 1) ) for dut in dut_lib.duts: Loading
DMT/core/dut_view.py +3 −1 Original line number Diff line number Diff line Loading @@ -742,6 +742,7 @@ class DutView(object): data: Union[DataFrame, Sweep, str, os.Pathlike], key: Union[str, None] = None, force: bool = True, validate: bool = True, **kwargs, ): """Add a measurement or simulation data to the DutView's data. Loading Loading @@ -787,6 +788,7 @@ class DutView(object): self.data[key] = data elif isinstance(data, Sweep): # simulation valid? if not validate: self.validate_simulation_successful(data) # try special import self.import_output_data(data) Loading
DMT/core/sim_con.py +23 −18 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ class SimCon(object, metaclass=Singleton): {"dut": dut_a, "sweep": sweep_a} for dut_a, sweep_a in itertools.product(dut, sweep) ] def run_and_read(self, force=False, remove_simulations=False, parallel_read=False): def run_and_read(self, force=False, remove_simulations=False, parallel_read=False, validate=True): """Run all queued simulations and load the results into the Duts' databases. Parameters Loading Loading @@ -195,14 +195,14 @@ class SimCon(object, metaclass=Singleton): if parallel_read: print("Checking which simulations need to be run in parallel:") sims_checked = parallel( delayed(_check_simulation_needed)(i_sim, n_tot, **sim) delayed(_check_simulation_needed)(i_sim, n_tot, validate=validate, **sim) for i_sim, sim in enumerate(self.sim_list) ) else: print("Checking which simulations need to be run:") # parallel not working with VAE modelcard currently since get_circuit is monkey patched sims_checked = [ _check_simulation_needed(i_sim, n_tot, **sim) _check_simulation_needed(i_sim, n_tot, validate=validate, **sim) for i_sim, sim in enumerate(self.sim_list) ] Loading Loading @@ -232,7 +232,7 @@ class SimCon(object, metaclass=Singleton): print("Reading in the results in parallel:") sims_read = parallel( delayed(_read_process_results)( process["success"], process["dut"], process["sweep"] process["success"], process["dut"], process["sweep"], validate=validate ) for process in process_finished ) Loading @@ -240,7 +240,7 @@ class SimCon(object, metaclass=Singleton): print("Reading in the results:") # parallel not working with VAE modelcard currently since get_circuit is monkey patched sims_read = [ _read_process_results(process["success"], process["dut"], process["sweep"]) _read_process_results(process["success"], process["dut"], process["sweep"], validate=validate) for process in process_finished ] all_sim_success = all(sim["success"] for sim in sims_read) Loading Loading @@ -800,7 +800,7 @@ class SimCon(object, metaclass=Singleton): return 0 def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=None): def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, validate=True, sweep_exists=None): """Function to check if the simulation is needed or already present in the database Parameter Loading @@ -821,6 +821,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No print_progress_bar(i_sim, n_tot, prefix="Progress", length=50) try: # was it simulated already successfully ? if validate: dut.validate_simulation_successful(sweep) print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and results are valid, only data needs to be read.", Loading @@ -830,8 +831,12 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No dut_name, sim_name, ) else: print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} not checked for validity.", ) logging.debug("The simulation folder of this simulation was %s", dut.get_sim_folder(sweep)) dut.add_data(sweep) dut.add_data(sweep, validate=validate) except SimulationFail: print( f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and failed.", Loading @@ -846,7 +851,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No return dut.data def _read_process_results(success, dut, sweep): def _read_process_results(success, dut, sweep, validate=True): """Read the process results Parameter Loading @@ -866,7 +871,7 @@ def _read_process_results(success, dut, sweep): # inform data_manager about the finished simulations try: if success: dut.add_data(sweep) dut.add_data(sweep, validate=validate) logging.info("Simulation of DuT %s with sweep %s successfull.", dut_name, sim_name) else: color_red = "\033[91m" Loading
DMT/ngspice/dut_ngspice.py +1 −1 Original line number Diff line number Diff line Loading @@ -585,7 +585,7 @@ class DutNgspice(DutCircuit): str_netlist += ( "set wr_vecnames\n" + f"tran {tau/40} {3*tau}\n" + f"wrdata output_ngspice_tr_{i_row}_{i_tr}.ngspice_tr alli allv\n" + f"wrdata output_ngspice_tr_{i_tr}.ngspice_tr alli allv\n" # TODO one file per ngspice variable "index", how to? + "unset wr_vecnames\n" ) Loading