| import argparse |
| import os |
| from collections import Counter |
| from pathlib import Path |
|
|
| import comet_ml |
| import yaml |
| from addict import Dict |
| from comet_ml import config |
|
|
|
|
| def parse_tags(tags_str): |
| all_tags = set(t.strip() for t in tags_str.split(",")) |
| keep_tags = set() |
| remove_tags = set() |
| for t in all_tags: |
| if "!" in t or "~" in t: |
| remove_tags.add(t[1:]) |
| else: |
| keep_tags.add(t) |
| return all_tags, keep_tags, remove_tags |
|
|
|
|
| def select_lambdas(vars): |
| """ |
| Create a specific file with the painter's lambdas |
| |
| Args: |
| vars (dict): output of locals() |
| """ |
| opts = vars["opts"] |
| dev = vars["args"].dev |
| lambdas = opts.train.lambdas.G.p |
| if not dev: |
| with open("./painter_lambdas.yaml", "w") as f: |
| yaml.safe_dump(lambdas.to_dict(), f) |
|
|
|
|
| def parse_value(v: str): |
| """ |
| Parses a string into bool or list or int or float or returns it as is |
| |
| Args: |
| v (str): value to parse |
| |
| Returns: |
| any: parsed value |
| """ |
| if v.lower() == "false": |
| return False |
| if v.lower() == "true": |
| return True |
| if v.startswith("[") and v.endswith("]"): |
| return [ |
| parse_value(sub_v) |
| for sub_v in v.replace("[", "").replace("]", "").split(", ") |
| ] |
| if "." in v: |
| try: |
| vv = float(v) |
| return vv |
| except ValueError: |
| return v |
| else: |
| try: |
| vv = int(v) |
| return vv |
| except ValueError: |
| return v |
|
|
|
|
| def parse_opts(summary): |
| """ |
| Parses a flatten_opts summary into an addict.Dict |
| |
| Args: |
| summary (list(dict)): List of dicts from exp.get_parameters_summary() |
| |
| Returns: |
| addict.Dict: parsed exp params |
| """ |
| opts = Dict() |
| for item in summary: |
| k, v = item["name"], parse_value(item["valueCurrent"]) |
| if "." in k: |
| d = opts |
| for subkey in k.split(".")[:-1]: |
| d = d[subkey] |
| d[k.split(".")[-1]] = v |
| else: |
| opts[k] = v |
| return opts |
|
|
|
|
| def has_right_tags(exp: comet_ml.Experiment, keep: set, remove: set) -> bool: |
| """ |
| All the "keep" tags should be in the experiment's tags |
| None of the "remove" tags should be in the experiment's tags. |
| |
| Args: |
| exp (comet_ml.Experiment): experiment to select (or not) |
| keep (set): tags the exp should have |
| remove (set): tags the exp cannot have |
| |
| Returns: |
| bool: should this exp be selected |
| """ |
| tags = set(exp.get_tags()) |
| has_all_keep = keep.intersection(tags) == keep |
| has_any_remove = remove.intersection(tags) |
| return has_all_keep and not has_any_remove |
|
|
|
|
| if __name__ == "__main__": |
| |
| |
| |
|
|
| parser = argparse.ArgumentParser() |
| parser.add_argument("-e", "--exp_id", type=str, default="") |
| parser.add_argument( |
| "-d", |
| "--download_dir", |
| type=str, |
| default=None, |
| help="Where to download the images", |
| ) |
| parser.add_argument( |
| "-s", "--step", default="last", type=str, help="`last`, `all` or `int`" |
| ) |
| parser.add_argument( |
| "-b", |
| "--base_dir", |
| default="./", |
| type=str, |
| help="if download_dir is not specified, download into base_dir/exp_id[:8]/", |
| ) |
| parser.add_argument( |
| "-t", |
| "--tags", |
| default="", |
| type=str, |
| help="download all images of all with a set of tags", |
| ) |
| parser.add_argument( |
| "-i", |
| "--id_length", |
| default=8, |
| type=int, |
| help="Length of the experiment's ID substring to make dirs: exp.id[:id_length]", |
| ) |
| parser.add_argument( |
| "--dev", |
| default=False, |
| action="store_true", |
| help="dry run: no mkdir, no download", |
| ) |
| parser.add_argument( |
| "-p", |
| "--post_processings", |
| default="", |
| type=str, |
| help="comma separated string list of post processing functions to apply", |
| ) |
| parser.add_argument( |
| "-r", |
| "--running", |
| default=False, |
| action="store_true", |
| help="only select running exps", |
| ) |
| args = parser.parse_args() |
| print(args) |
|
|
| |
| |
| |
|
|
| POST_PROCESSINGS = {"select_lambdas": select_lambdas} |
| post_processes = list( |
| filter( |
| lambda p: p is not None, |
| [POST_PROCESSINGS.get(k.strip()) for k in args.post_processings.split(",")], |
| ) |
| ) |
|
|
| |
| |
| |
| |
|
|
| download_dir = Path(args.download_dir or Path(args.base_dir)).resolve() |
| if not args.dev: |
| download_dir.mkdir(parents=True, exist_ok=True) |
|
|
| |
| |
| |
|
|
| step = None |
| try: |
| step = int(args.step) |
| except ValueError: |
| step = args.step |
| assert step in {"last", "all"} |
|
|
| api = comet_ml.api.API() |
|
|
| |
| |
| |
| if not args.tags: |
| assert args.exp_id |
| exps = [api.get_experiment_by_id(args.exp_id)] |
| else: |
| all_tags, keep_tags, remove_tags = parse_tags(args.tags) |
| download_dir = download_dir / "&".join(sorted(all_tags)) |
|
|
| print("Selecting experiments with tags", all_tags) |
| conf = dict(config.get_config()) |
| exps = api.get_experiments( |
| workspace=conf.get("comet.workspace"), |
| project_name=conf.get("comet.project_name") or "climategan", |
| ) |
| exps = list(filter(lambda e: has_right_tags(e, keep_tags, remove_tags), exps)) |
| if args.running: |
| exps = [e for e in exps if e.alive] |
|
|
| |
| |
| |
|
|
| print( |
| "Processing {} experiments in {} with post processes {}".format( |
| len(exps), str(download_dir), post_processes |
| ) |
| ) |
| assert all( |
| [v == 1 for v in Counter([e.id[: args.id_length] for e in exps]).values()] |
| ), "Experiment ID conflict, use a larger --id_length" |
|
|
| for e, exp in enumerate(exps): |
| |
| |
| |
| cropped_id = exp.id[: args.id_length] |
| ddir = (download_dir / cropped_id).resolve() |
| if not args.dev: |
| ddir.mkdir(parents=True, exist_ok=True) |
|
|
| |
| |
| |
| ims = [asset for asset in exp.get_asset_list() if asset["image"] is True] |
|
|
| |
| |
| |
|
|
| if step == "last": |
| curr_step = max(i["step"] or -1 for i in ims) |
| if curr_step == -1: |
| curr_step = None |
| else: |
| curr_step = step |
|
|
| ims = [i for i in ims if (i["step"] == curr_step) or (step == "all")] |
|
|
| ddir = ddir / str(curr_step) |
| if not args.dev: |
| ddir.mkdir(parents=True, exist_ok=True) |
|
|
| |
| |
| |
| summary = exp.get_parameters_summary() |
| opts = parse_opts(summary) |
| if not args.dev: |
| with open("./url.txt", "w") as f: |
| f.write(exp.url) |
| with open("./opts.yaml", "w") as f: |
| yaml.safe_dump(opts.to_dict(), f) |
|
|
| |
| |
| |
| print( |
| " >>> Downloading exp {}'s image at step `{}` into {}".format( |
| cropped_id, args.step, str(ddir) |
| ) |
| ) |
|
|
| for i, im in enumerate(ims): |
| if not Path(im["fileName"] + "_{}.png".format(curr_step)).exists(): |
| print( |
| "\nDownloading exp {}/{} image {}/{}: {} in {}".format( |
| e + 1, len(exps), i + 1, len(ims), im["fileName"], ddir |
| ) |
| ) |
| if not args.dev: |
| assert len(im["curlDownload"].split(" > ")) == 2 |
| curl_command = im["curlDownload"].split(" > ")[0] |
| file_stem = Path(im["curlDownload"].split(" > ")[1]).stem |
|
|
| file_path = ( |
| f'"{str(ddir / file_stem)}_{cropped_id}_{curr_step}.png"' |
| ) |
|
|
| signal = os.system(f"{curl_command} > {file_path}") |
| for p in post_processes: |
| p(locals()) |
|
|