|
| 1 | +"""Tools to facilitate copying files. |
| 2 | +
|
| 3 | +This is mainly aimed at cases where a file is being copied with some sort of |
| 4 | +modification, or where CVs need to be disk-cached. |
| 5 | +""" |
| 6 | + |
| 7 | +import click |
| 8 | +from tqdm.auto import tqdm |
| 9 | +from paths_cli.parameters import ( |
| 10 | + Option, Argument, HELP_MULTIPLE, StorageLoader, OPSStorageLoadNames |
| 11 | +) |
| 12 | + |
| 13 | +INPUT_APPEND_FILE = StorageLoader( |
| 14 | + param=Argument('append_file', |
| 15 | + type=click.Path(writable=True, readable=True)), |
| 16 | + mode='a' |
| 17 | +) |
| 18 | + |
| 19 | +class PrecomputeLoadNames(OPSStorageLoadNames): |
| 20 | + def get(self, storage, name): |
| 21 | + if len(name) == 0: |
| 22 | + return list(getattr(storage, self.store)) |
| 23 | + elif len(name) == 1 and name[0] == '--': |
| 24 | + return [] |
| 25 | + |
| 26 | + return super(PrecomputeLoadNames, self).get(storage, name) |
| 27 | + |
| 28 | +PRECOMPUTE_CVS = PrecomputeLoadNames( |
| 29 | + param=Option('--cv', type=str, multiple=True, |
| 30 | + help=('name of CV to precompute; if not specified all will' |
| 31 | + + ' be used' + HELP_MULTIPLE |
| 32 | + + ' (use `--cv --` to disable precomputing)')), |
| 33 | + store='cvs' |
| 34 | +) |
| 35 | + |
| 36 | + |
| 37 | +def make_blocks(listlike, blocksize): |
| 38 | + """Make blocks out of a listlike object. |
| 39 | +
|
| 40 | + Parameters |
| 41 | + ---------- |
| 42 | + listlike : Iterable |
| 43 | + must be an iterable that supports slicing |
| 44 | + blocksize : int |
| 45 | + number of objects per block |
| 46 | +
|
| 47 | +
|
| 48 | + Returns |
| 49 | + ------- |
| 50 | + List[List[Any]] : |
| 51 | + the input iterable chunked into blocks |
| 52 | + """ |
| 53 | + n_objs = len(listlike) |
| 54 | + partial_block = 1 if n_objs % blocksize else 0 |
| 55 | + n_blocks = (n_objs // blocksize) + partial_block |
| 56 | + minval = lambda i: i * blocksize |
| 57 | + maxval = lambda i: min((i + 1) * blocksize, n_objs) |
| 58 | + blocks = [listlike[minval(i):maxval(i)] for i in range(n_blocks)] |
| 59 | + return blocks |
| 60 | + |
| 61 | + |
| 62 | +def precompute_cvs(cvs, block): |
| 63 | + """Calculate a CV for a a given block. |
| 64 | +
|
| 65 | + Parameters |
| 66 | + ---------- |
| 67 | + cvs : List[:class:`openpathsampling.CollectiveVariable`] |
| 68 | + CVs to precompute |
| 69 | + block : List[Any] |
| 70 | + b |
| 71 | + """ |
| 72 | + for cv in cvs: |
| 73 | + cv.enable_diskcache() |
| 74 | + _ = cv(block) |
| 75 | + |
| 76 | + |
| 77 | +def precompute_cvs_func_and_inputs(input_storage, cvs, blocksize): |
| 78 | + """ |
| 79 | + Parameters |
| 80 | + ---------- |
| 81 | + input_storage : :class:`openpathsampling.Storage` |
| 82 | + storage file to read from |
| 83 | + cvs : List[:class:`openpathsampling.CollectiveVariable`] |
| 84 | + list of CVs to precompute; if None, use all CVs in ``input_storage`` |
| 85 | + blocksize : int |
| 86 | + number of snapshots per block to precompute |
| 87 | + """ |
| 88 | + if cvs is None: |
| 89 | + cvs = list(input_storage.cvs) |
| 90 | + |
| 91 | + precompute_func = lambda inps: precompute_cvs(cvs, inps) |
| 92 | + snapshot_proxies = input_storage.snapshots.all().as_proxies() |
| 93 | + snapshot_blocks = make_blocks(snapshot_proxies, blocksize) |
| 94 | + return precompute_func, snapshot_blocks |
| 95 | + |
| 96 | + |
| 97 | +def rewrite_file(stage_names, stage_mapping): |
| 98 | + stages = tqdm(stage_names, desc="All stages") |
| 99 | + for stage in stages: |
| 100 | + store_func, inputs = stage_mapping[stage] |
| 101 | + desc = "This stage: {}".format(stage) |
| 102 | + for obj in tqdm(inputs, desc=desc, leave=False): |
| 103 | + store_func(obj) |
0 commit comments