Source code for pestifer.subcommands.build

# Author: Cameron F. Abrams, <cfa22@drexel.edu>

"""
Implementation of the ``build`` subcommand for launching system preparations.
"""

import datetime
import logging
import os
import shutil
import time
from dataclasses import dataclass, field

logger = logging.getLogger(__name__)

from ..core.controller import Controller
from ..core.config import Config
from ..cli.subcommand import Subcommand
from ..util.stringthings import __pestifer_version__
from ..util.util import hmsf

[docs] @dataclass class RunSubcommand(Subcommand): name: str = 'build' aliases: list = field(default_factory=lambda: ['run']) long_help: str = 'Prepare a system according to instructions in the config file.' short_help: str = 'prepare a system' func_returns_type: type = Controller
[docs] def add_subparser(self, subparsers): super().add_subparser(subparsers) self.parser.add_argument('config', type=str, default=None, help='input configuration file in YAML format') self.parser.add_argument('--output-dir', type=str, default='./', help='name of output directory relative to CWD (default: %(default)s)') self.parser.add_argument('--gpu', default=False, action='store_true', help='force run on GPU') self.parser.add_argument('--ncpus', type=int, default=0, help='number of NAMD processing elements (0 = auto-detect)') self.parser.add_argument('--complete-config', default=False, action='store_true', help='write complete config file') return self.parser
[docs] @staticmethod def func(args, **kwargs): """ Run the ``pestifer build`` command with the specified configuration file. """ if args.output_dir != './': exec_dir = os.getcwd() if not os.path.exists(args.output_dir): os.mkdir(args.output_dir) if not os.path.exists(os.path.join(args.output_dir, args.config)): shutil.copy(args.config, args.output_dir) os.chdir(args.output_dir) # Set up the Controller and execute tasks begin_time = time.time() configname = args.config # include date and time in the message below logger.info(f'pestifer v. {__pestifer_version__} begins at {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(begin_time))} with config {configname}') allowed_extensions = ['.yaml', '.yml', '.y'] cbase, cext = os.path.splitext(configname) if not cext: fil = [os.path.exists(f'{cbase}{ext}') for ext in allowed_extensions] if any(fil): iix = fil.index(True) configname = f'{cbase}{allowed_extensions[iix]}' config = Config(userfile=configname, ncpus_override=args.ncpus, **kwargs).configure_new() C = Controller().configure(config) if args.gpu: C.config.namd_type = 'gpu' C.config.scripters['namd'].namd_type = 'gpu' if args.complete_config: C.write_complete_config(f'{cbase}-complete.yaml') report = C.do_tasks() end_time = time.time() elapsed_time_s = datetime.timedelta(seconds=(end_time - begin_time)) logger.info(f'pestifer ends. Elapsed time {time.strftime("%H:%M:%S", time.gmtime(elapsed_time_s.seconds))}.') logger.info(f'Task durations:') maxnamelen = max([len(t.taskname) for t in C.tasks]) if len(C.tasks) > 0 else 0 name_format = f'{{:>{maxnamelen}s}}' for task in report.values(): logger.info(f' - {name_format.format(task["taskname"])}: {hmsf(task["duration"])} ({task["duration_frac"]:>5.1%})') if args.output_dir != './': os.chdir(exec_dir) return C