def new_experiment(name: str, sample_name: Optional[str], format_string: str = "{}-{}-{}", conn: Optional[ConnectionPlus] = None) -> Experiment: """ Create a new experiment (in the database file from config) Args: name: the name of the experiment sample_name: the name of the current sample format_string: basic format string for table-name must contain 3 placeholders. conn: connection to the database. If not supplied, a new connection to the DB file specified in the config is made Returns: the new experiment """ sample_name = sample_name or "some_sample" conn = conn or connect(get_DB_location()) exp_ids = get_matching_exp_ids(conn, name=name, sample_name=sample_name) if len(exp_ids) >= 1: log.warning( f"There is (are) already experiment(s) with the name of {name} " f"and sample name of {sample_name} in the database.") experiment = Experiment(name=name, sample_name=sample_name, format_string=format_string, conn=conn) _set_default_experiment_id(path_to_dbfile(conn), experiment.exp_id) return experiment
def _create_exp_if_needed(target_conn: ConnectionPlus, exp_name: str, sample_name: str, fmt_str: str, start_time: float, end_time: Union[float, None]) -> int: """ Look up in the database whether an experiment already exists and create it if it doesn't. Note that experiments do not have GUIDs, so this method is not guaranteed to work. Matching names and times is the best we can do. """ matching_exp_ids = get_matching_exp_ids(target_conn, name=exp_name, sample_name=sample_name, format_string=fmt_str, start_time=start_time, end_time=end_time) if len(matching_exp_ids) > 1: exp_id = matching_exp_ids[0] warn(f'{len(matching_exp_ids)} experiments found in target DB that ' 'match name, sample_name, fmt_str, start_time, and end_time. ' f'Inserting into the experiment with exp_id={exp_id}.') return exp_id if len(matching_exp_ids) == 1: return matching_exp_ids[0] else: lastrowid = new_experiment(target_conn, name=exp_name, sample_name=sample_name, format_string=fmt_str, start_time=start_time, end_time=end_time) return lastrowid
def load_experiment_by_name( name: str, sample: Optional[str] = None, conn: Optional[ConnectionPlus] = None, load_last_duplicate: bool = False, ) -> Experiment: """ Try to load experiment with the specified name. Nothing stops you from having many experiments with the same name and sample name. In that case this won't work unless load_last_duplicate is set to True. Then, the last of duplicated experiments will be loaded. Args: name: the name of the experiment sample: the name of the sample load_last_duplicate: If True, prevent raising error for having multiple experiments with the same name and sample name, and load the last duplicated experiment, instead. conn: connection to the database. If not supplied, a new connection to the DB file specified in the config is made Returns: the requested experiment Raises: ValueError either if the name and sample name are not unique, unless load_last_duplicate is True, or if no experiment found for the supplied name and sample. . """ conn = conn or connect(get_DB_location()) if sample is not None: args_to_find = {"name": name, "sample_name": sample} else: args_to_find = {"name": name} exp_ids = get_matching_exp_ids(conn, **args_to_find) if len(exp_ids) == 0: raise ValueError("Experiment not found") elif len(exp_ids) > 1: _repr = [] for exp_id in exp_ids: exp = load_experiment(exp_id, conn=conn) s = (f"exp_id:{exp.exp_id} ({exp.name}-{exp.sample_name})" f" started at ({exp.started_at})") _repr.append(s) _repr_str = "\n".join(_repr) if load_last_duplicate: e = exp else: raise ValueError(f"Many experiments matching your request" f" found:\n{_repr_str}") else: e = Experiment(exp_id=exp_ids[0], conn=conn) _set_default_experiment_id(path_to_dbfile(conn), e.exp_id) return e