def exportfamily(self, *args): '''Export a PAW potential family into a folder''' from aiida.backends.utils import load_dbenv, is_dbenv_loaded from aiida.orm import DataFactory from aiida.common.exceptions import NotExistent import argparse import os from os.path import abspath, expanduser parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Export a PAW potential family into a folder') parser.add_argument('--name', nargs=1, type=str, default=None, help='name of the folder, defaults to ' 'potpaw_<family_name>.') parser.add_argument('folder', help='path to where the potpaw ' 'folder should be created') parser.add_argument('family_name') params = parser.parse_args(args) folder = abspath(expanduser(params.folder)) if not is_dbenv_loaded(): load_dbenv() Paw = DataFactory('vasp.paw') try: group = Paw.get_famgroup(params.family_name) except NotExistent: print >> sys.stderr, ('paw family {} not found'.format( params.family_name)) #create folder potpaw = params.name and params.name[0] or os.path.join( folder, 'potpaw_%s' % params.family_name) for paw in group.nodes: pawf = os.path.join(potpaw, paw.symbol) if not os.path.exists(pawf): os.makedirs(pawf) pp = os.path.join(pawf, 'POTCAR') cp = os.path.join(pawf, 'PSCTR') isfile_msg = 'file {} is already present in the destination folder.' if not os.path.isfile(pp): with open(pp, 'w') as dest: with open(paw.potcar) as src: dest.write(src.read()) else: print isfile_msg.format(os.path.join(paw.symbol, 'POTCAR')) if not os.path.isfile(cp): try: with open(paw.psctr) as src: with open(cp, 'w') as dest: dest.write(src.read()) except OSError: pass else: print isfile_msg.format(os.path.join(paw.symbol, 'PSCTR'))
def exportfamily(family, directory): """ Export a pseudopotential family into a new directory. """ from aiida import is_dbenv_loaded, load_dbenv if not is_dbenv_loaded(): load_dbenv() import os from aiida.common.exceptions import NotExistent from aiida.orm import DataFactory PsfData = DataFactory('siesta.psf') try: group = PsfData.get_psf_group(family) except NotExistent: click.echo("PSF family {} not found".format(family), err=True) try: os.makedirs(directory) for pseudo in group.nodes: dest_path = os.path.join(directory, pseudo.filename) with open(dest_path, 'w') as dest: with pseudo._get_folder_pathsubfolder.open( pseudo.filename) as source: dest.write(source.read()) except OSError: click.echo( "Destination directory {} exists; aborted".format(directory),err=True)
def group_description(self, *args): """ Edit the group description. """ if not is_dbenv_loaded(): load_dbenv() import argparse from aiida.orm import Group as G from aiida.common.exceptions import NotExistent parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Change the description of a given group.') parser.add_argument('PK', type=int, help="The PK of the group for which " "you want to edit the description") parser.add_argument('description', type=str, help="The new description. If not provided, " "just show the current description.") args = list(args) parsed_args = parser.parse_args(args) group_pk = parsed_args.PK try: group = G(dbgroup=group_pk) except NotExistent as e: print >> sys.stderr, "Error: {}.".format(e.message) sys.exit(1) group.description = parsed_args.description
def plugins(entry_point): from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv() from aiida.common.exceptions import LoadingPluginFailed, MissingPluginError from aiida.common.pluginloader import plugin_list, get_plugin if entry_point: try: plugin = get_plugin('workflows', entry_point) except (LoadingPluginFailed, MissingPluginError) as exception: click.echo("Error: {}".format(exception)) else: click.echo(plugin.get_description()) else: entry_points = sorted(plugin_list('workflows')) if entry_points: click.echo('Registered workflow entry points:') for entry_point in entry_points: click.echo("* {}".format(entry_point)) click.echo( "\nPass the entry point of a workflow as an argument to display detailed information" ) else: click.echo("# No workflows found")
def do_list(past_days, limit): """ Return a list of running workflows on screen """ from aiida.common.utils import str_timedelta from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv() import aiida.utils.timezone as timezone from aiida.orm.mixins import SealableMixin _SEALED_ATTRIBUTE_KEY = 'attributes.{}'.format(SealableMixin.SEALED_KEY) now = timezone.now() table = [] for res in _build_query(limit=limit, past_days=past_days): calc = res['calculation'] creation_time = str_timedelta(timezone.delta(calc['ctime'], now), negative_to_zero=True, max_num_fields=1) table.append([ calc['id'], creation_time, calc['type'], str(calc[_SEALED_ATTRIBUTE_KEY]) ]) print(tabulate(table, headers=["PID", "Creation time", "Type", "Sealed"]))
def calculation_outputls(self, *args): """ Show the list of output files of a calculation node. It lists the files in the 'path' subdirectory of the output node of files retrieved by the parser. Therefore, this will not work before files are retrieved by the daemon. Use the -h option for more help on the command line options. """ import argparse from aiida.common.exceptions import NotExistent from aiida.cmdline.commands.node import list_repo_files parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='List ourput files in the repository folder.') parser.add_argument('calc', metavar='PK', type=int, help='The pk of the calculation') parser.add_argument('-p', '--path', type=str, default='', nargs='?', help="The relative path of the file you " "want to show. If not specified, show content" " of all the 'path' directory") parser.add_argument('-c', '--color', action='store_true', help="Color folders with a different color") args = list(args) parsed_args = parser.parse_args(args) if not is_dbenv_loaded(): load_dbenv() try: calc = load_node(parsed_args.calc) except NotExistent as e: print >> sys.stderr, e.message sys.exit(1) try: parsed_node = calc.out.retrieved except AttributeError: print >> sys.stderr, ("No 'retrieved' node found. Have the " "calculation files already been retrieved?") sys.exit(1) try: list_repo_files(parsed_node, os.path.join('path', parsed_args.path), parsed_args.color) except ValueError as e: print >> sys.stderr, e.message sys.exit(1)
def daemon_logshow(self, *args): """ Show the log of the daemon, press CTRL+C to quit. """ if not is_dbenv_loaded(): from aiida.backends.utils import load_dbenv load_dbenv(process='daemon') if args: print >> sys.stderr, ( "No arguments allowed for the '{}' command.".format( self.get_full_command_name())) sys.exit(1) pid = self.get_daemon_pid() if (pid == None): print "Daemon not running (cannot find the PID for it)" return try: process = subprocess.Popen( "supervisorctl -c {} tail -f aiida-daemon".format( self.conffile_full_path), shell=True) # , stdout=subprocess.PIPE) process.wait() except KeyboardInterrupt: # exit on CTRL+C process.kill()
def computer_delete(self, *args): """ Configure the authentication information for a given computer Does not delete the computer if there are calculations that are using it. """ if not is_dbenv_loaded(): load_dbenv() from aiida.common.exceptions import (NotExistent, InvalidOperation) from aiida.orm.computer import delete_computer if len(args) != 1: print >> sys.stderr, ( "after 'computer delete' there should be one " "argument only, being the computer name.") sys.exit(1) computername = args[0] try: computer = self.get_computer(name=computername) except NotExistent: print >> sys.stderr, "No computer exists with name '{}'".format( computername) sys.exit(1) try: delete_computer(computer) except InvalidOperation as e: print >> sys.stderr, e.message sys.exit(1) print "Computer '{}' deleted.".format(computername)
def run(self, *args): """ Show node information. """ import argparse from aiida.common.exceptions import NotExistent parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Show information of a node.') parser.add_argument('pk', type=int, default=None, nargs="+", help="ID of the node.") parser.add_argument('-d', '--depth', action='store', default=1, metavar="N", type=int, help="Add children of shown nodes up to Nth " "level. Default 0") args = list(args) parsed_args = parser.parse_args(args) if not is_dbenv_loaded(): load_dbenv() for pk in parsed_args.pk: try: n = load_node(pk) self.print_node_tree(n, parsed_args.depth) except NotExistent as e: print >> sys.stderr, e.message sys.exit(1) if len(parsed_args.pk) > 1: print ""
def show(identifiers, uuid, print_groups): from aiida.common.exceptions import NotExistent from aiida.common.exceptions import MultipleObjectsError if not is_dbenv_loaded(): load_dbenv() for id in identifiers: try: if uuid: try: n = load_node(uuid=id) except MultipleObjectsError: click.echo("More than one node found. Please provide " "longer starting pattern for uuid.", err=True) return else: try: ids = int(id) except ValueError: click.echo("The pk/id can not be a string. Please provide " "an integer.", err=True) return n = load_node(pk=int(ids)) print_node_info(n, print_groups=print_groups) except NotExistent as e: click.echo(e.message, err=True) sys.exit(1) if len(identifiers) > 1: click.echo("")
def do_report(pk, levelname, order_by): """ Return a list of recorded log messages for the WorkChain with pk=PK """ from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv() from aiida.orm.backend import construct from aiida.orm.log import OrderSpecifier, ASCENDING, DESCENDING backend = construct() order_by = [OrderSpecifier(order_by, ASCENDING)] filters = { 'objpk': pk, } if levelname: filters['levelname'] = levelname entries = backend.log.find(filter_by=filters, order_by=order_by) object_ids = [entry.id for entry in entries] levelnames = [len(entry.levelname) for entry in entries] width_id = len(str(max(object_ids))) width_levelname = max(levelnames) for entry in entries: print '{time:%Y-%m-%d %H:%M:%S} [{id:<{width_id}} | {levelname:>{width_levelname}}]: {message}'.format( id=entry.id, levelname=entry.levelname, message=entry.message, time=entry.time, width_id=width_id, width_levelname=width_levelname)
def group_create(self, *args): """ Create a new empty group. """ if not is_dbenv_loaded(): load_dbenv() import argparse from aiida.orm import Group as G parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Create a new empty group.') parser.add_argument('GROUPNAME', help="The name of the new group") args = list(args) parsed_args = parser.parse_args(args) group_name = parsed_args.GROUPNAME group, created = G.get_or_create(name=group_name) if created: print "Group created with PK = {} and name '{}'".format( group.pk, group.name) else: print "Group '{}' already exists, PK = {}".format( group.name, group.pk)
def print_report(self, *args): """ Print the report of a workflow. """ from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv() from aiida.orm.utils import load_workflow from aiida.common.exceptions import NotExistent if len(args) != 1: print >> sys.stderr, "You have to pass a valid workflow PK as a parameter." sys.exit(1) try: pk = int(args[0]) except ValueError: print >> sys.stderr, "You have to pass a valid workflow PK as a parameter." sys.exit(1) try: w = load_workflow(pk) except NotExistent: print >> sys.stderr, "No workflow with PK={} found.".format(pk) sys.exit(1) print "### WORKFLOW pk: {} ###".format(pk) print "\n".join(w.get_report())
def daemon_logshow(self, *args): """ Show the log of the daemon, press CTRL+C to quit. """ if not is_dbenv_loaded(): from aiida.backends.utils import load_dbenv load_dbenv(process='daemon') if args: print >> sys.stderr, ( "No arguments allowed for the '{}' command.".format( self.get_full_command_name())) sys.exit(1) pid = self.get_daemon_pid() if (pid == None): print "Daemon not running (cannot find the PID for it)" return try: currenv = _get_env_with_venv_bin() process = subprocess.Popen( [ "tail", "-f", self.logfile, ], env=currenv) # , stdout=subprocess.PIPE) process.wait() except KeyboardInterrupt: # exit on CTRL+C process.kill()
def calculation_gotocomputer(self, *args): """ Open a shell to the calc folder on the cluster This command opens a ssh connection to the scratch folder on the remote computer on which the calculation is being/has been executed. """ from aiida.common.exceptions import NotExistent if not is_dbenv_loaded(): load_dbenv() try: calc_id = args[0] except IndexError: print >> sys.stderr, "Pass as further argument a calculation ID or UUID." sys.exit(1) try: pk = int(calc_id) is_pk = True except ValueError: uuid = calc_id is_pk = False print "Loading environment..." from aiida.orm import JobCalculation try: if is_pk: calc = load_node(pk) else: calc = load_node(uuid) except NotExistent: print >> sys.stderr, "No node exists with ID={}.".format(calc_id) sys.exit(1) if not isinstance(calc, JobCalculation): print >> sys.stderr, "Node with ID={} is not a calculation; it is a {}".format( calc_id, calc.__class__.__name__) sys.exit(1) # get the transport try: t = calc._get_transport() except NotExistent as e: print >> sys.stderr, e.message sys.exit(1) # get the remote directory remotedir = calc._get_remote_workdir() if not remotedir: print >> sys.stderr, "No remote work directory is set for this calculation!" print >> sys.stderr, "(It is possible that the daemon did not submit the calculation yet)" sys.exit(1) # get the command to run (does not require to open the connection!) cmd_to_run = t.gotocomputer_command(remotedir) # Connect (execute command) print "Going the the remote folder..." # print cmd_to_run os.system(cmd_to_run)
def comment_remove(self, *args): """ Remove comments. The user can only remove its own comments """ # Note: in fact, the user can still manually delete any comment import argparse from aiida.backends.utils import get_automatic_user if not is_dbenv_loaded(): load_dbenv() user = get_automatic_user() parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Remove comments of a node.') parser.add_argument('pk', metavar='PK', type=int, help='The pk (an integer) of the node') parser.add_argument('id', metavar='ID', type=int, default=None, nargs='?', help='#ID of the comment to be removed from node #PK') parser.add_argument('-a', '--all', action='store_true', default=False, help='If used, deletes all the comments of the active user attached to the node') parsed_args = parser.parse_args(args) if parsed_args.id is None and not parsed_args.all: print "One argument between -a and ID must be provided" sys.exit(1) if parsed_args.id is not None and parsed_args.all: print "Only one between -a and ID should be provided" sys.exit(1) node = load_node(parsed_args.pk) allowed_trues = ['1', 't', 'true', 'y', 'yes'] if parsed_args.all: sys.stdout.write("Delete all comments of user {}? ".format(user)) inpread = sys.stdin.readline() do_I_delete = True if inpread.strip().lower() in allowed_trues else False if not do_I_delete: print "Not deleting comment. Aborting." sys.exit(1) else: comments = node.get_comment_obj(user=user) for comment in comments: comment.delete() print("Deleted {} comments.".format(len(comments))) else: sys.stdout.write("Delete comment? ") inpread = sys.stdin.readline() do_I_delete = True if inpread.strip().lower() in allowed_trues else False if not do_I_delete: print "Not deleting comment. Aborting." sys.exit(1) else: from aiida.orm.implementation import Comment as CommentOrm c = CommentOrm(id=parsed_args.id, user=user) c.delete()
def daemon_status(self, *args): """ Print the status of the daemon """ if not is_dbenv_loaded(): from aiida.backends.utils import load_dbenv load_dbenv(process='daemon') if args: print >> sys.stderr, ( "No arguments allowed for the '{}' command.".format( self.get_full_command_name())) sys.exit(1) from aiida.utils import timezone from aiida.daemon.timestamps import get_most_recent_daemon_timestamp from aiida.common.utils import str_timedelta from pytz import UTC most_recent_timestamp = get_most_recent_daemon_timestamp() if most_recent_timestamp is not None: timestamp_delta = (timezone.datetime.now(tz=UTC) - most_recent_timestamp) print("# Most recent daemon timestamp:{}".format( str_timedelta(timestamp_delta))) else: print("# Most recent daemon timestamp: [Never]") pid = self.get_daemon_pid() if pid is None: print "Daemon not running (cannot find the PID for it)" return import psutil def create_time(p): return datetime.fromtimestamp(p.create_time()) try: daemon_process = psutil.Process(self.get_daemon_pid()) except psutil.NoSuchProcess: print "Daemon process can not be found" return print "Daemon is running as pid {pid} since {time}, child processes:".format( pid=daemon_process.pid, time=create_time(daemon_process)) workers = daemon_process.children(recursive=True) if workers: for worker in workers: print " * {name}[{pid}] {status:>10}, started at {time:%Y-%m-%d %H:%M:%S}".format( name=worker.name(), pid=worker.pid, status=worker.status(), time=create_time(worker)) else: print "... but it does not have any child processes, which is wrong"
def load_dbenv_if_not_loaded(**kwargs): """ load dbenv if necessary, run spinner meanwhile to show command hasn't crashed """ from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): with cli_spinner(): load_dbenv(**kwargs)
def try_load_dbenv(*argc, **argv): """ Run `load_dbenv` unless the dbenv has already been loaded. """ if not is_dbenv_loaded(): load_dbenv(*argc, **argv) return True return False
def calculation_inputcat(self, *args): """ Show an input file of a calculation node. It shows the files in the raw_input subdirectory. Use the -h option for more help on the command line options. """ from aiida.cmdline.commands.node import cat_repo_files from aiida.common.exceptions import NotExistent import argparse parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Output the content of a file in the repository folder.') parser.add_argument('calc', metavar='PK', type=int, help='The pk of the calculation') parser.add_argument('-p', '--path', type=str, default=None, nargs='?', help="The relative path of the file you " "want to show. Take the default input file if " "it is not specified") args = list(args) parsed_args = parser.parse_args(args) if not is_dbenv_loaded(): load_dbenv() from aiida.common.old_pluginloader import get_class_typestring try: calc = load_node(parsed_args.calc) except NotExistent as e: print >> sys.stderr, e.message sys.exit(1) path = parsed_args.path if path is None: path = calc._DEFAULT_INPUT_FILE if path is None: base_class, plugin_string, class_name = get_class_typestring( calc._plugin_type_string) print >> sys.stderr, ("Calculation '{}' does not define a " "default input file. Please specify a path " "explicitly".format(plugin_string)) sys.exit(1) try: cat_repo_files(calc, os.path.join('raw_input', path)) except ValueError as e: print >> sys.stderr, e.message sys.exit(1) except IOError as e: import errno # Ignore Broken pipe errors, re-raise everything else if e.errno == errno.EPIPE: pass else: raise
def calculation_res(self, *args): """ Print all or somoe data from the "res" output node. """ from aiida.common.exceptions import NotExistent from aiida.cmdline import print_dictionary import argparse parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Show calculation results (from calc.res)') parser.add_argument('PK', type=int, default=None, help="PK of the calculation object whose results " "must be shown.") parser.add_argument('-f', '--format', type=str, default='json+date', help="Format for the output.") parser.add_argument('-k', '--keys', nargs='+', type=str, help="Show only the selected keys.") args = list(args) parsed_args = parser.parse_args(args) if not is_dbenv_loaded(): load_dbenv() try: calc = load_node(int(parsed_args.PK)) except ValueError: print >> sys.stderr, "*** {}: Not a valid PK".format( parsed_args.PK) sys.exit(1) except NotExistent: print >> sys.stderr, "*** {}: Not a valid calculation".format( parsed_args.PK) sys.exit(1) full_dict = calc.res._get_dict() if parsed_args.keys: try: the_dict = {k: full_dict[k] for k in parsed_args.keys} except KeyError as e: print >> sys.stderr, ("The key '{}' was not found in the .res " "dictionary".format(e.message)) sys.exit(1) else: # Return all elements the_dict = full_dict print_dictionary(the_dict, format=parsed_args.format)
def calculation_logshow(self, *args): from aiida.common.exceptions import NotExistent from aiida.backends.utils import get_log_messages from aiida.common.datastructures import calc_states if not is_dbenv_loaded(): load_dbenv() for calc_pk in args: try: calc = load_node(int(calc_pk)) except ValueError: print "*** {}: Not a valid PK".format(calc_pk) continue except NotExistent: print "*** {}: Not a valid calculation".format(calc_pk) continue log_messages = get_log_messages(calc) label_string = " [{}]".format(calc.label) if calc.label else "" state = calc.get_state() if state == calc_states.WITHSCHEDULER: sched_state = calc.get_scheduler_state() if sched_state is None: sched_state = "(unknown)" state += ", scheduler state: {}".format(sched_state) print "*** {}{}: {}".format(calc_pk, label_string, state) sched_out = calc.get_scheduler_output() sched_err = calc.get_scheduler_error() if sched_out is None: print "*** Scheduler output: N/A" elif sched_out: print "*** Scheduler output:" print sched_out else: print "*** (empty scheduler output file)" if sched_err is None: print "*** Scheduler errors: N/A" elif sched_err: print "*** Scheduler errors:" print sched_err else: print "*** (empty scheduler errors file)" if log_messages: print "*** {} LOG MESSAGES:".format(len(log_messages)) else: print "*** 0 LOG MESSAGES" for log in log_messages: print "+-> {} at {}".format(log['levelname'], log['time']) # Print the message, with a few spaces in front of each line print "\n".join( ["| {}".format(_) for _ in log['message'].splitlines()])
def listfamilies(element, with_description): """ Print on screen the list of installed PSF-pseudo families. """ from aiida import is_dbenv_loaded, load_dbenv if not is_dbenv_loaded(): load_dbenv() from aiida.orm import DataFactory from aiida_siesta.data.psf import PSFGROUP_TYPE PsfData = DataFactory('siesta.psf') from aiida.orm.querybuilder import QueryBuilder from aiida.orm.group import Group qb = QueryBuilder() qb.append(PsfData, tag='psfdata') if element: qb.add_filter(PsfData, {'attributes.element': {'in': element}}) qb.append( Group, group_of='psfdata', tag='group', project=["name", "description"], filters={ "type": { '==': PSFGROUP_TYPE } }) qb.distinct() if qb.count() > 0: for res in qb.dict(): group_name = res.get("group").get("name") group_desc = res.get("group").get("description") qb = QueryBuilder() qb.append( Group, tag='thisgroup', filters={ "name": { 'like': group_name } }) qb.append(PsfData, project=["id"], member_of='thisgroup') if with_description: description_string = ": {}".format(group_desc) else: description_string = "" click.echo("* {} [{} pseudos]{}".format(group_name, qb.count(), description_string)) else: click.echo("No valid PSF pseudopotential family found.", err=True)
def comment_update(self, *args): """ Update a comment """ import argparse from aiida.backends.utils import get_automatic_user if not is_dbenv_loaded(): load_dbenv() user = get_automatic_user() parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Add a comment to a node in the database.') parser.add_argument('pk', metavar='PK', type=int, help='The pk (an integer) of the node') parser.add_argument('id', metavar='ID', type=int, help='Identify the comment to update by ID') parser.add_argument( '-c', '--comment', type=str, default=None, help='The comment (a string) to be added to the node') parsed_args = parser.parse_args(args) # read the comment from terminal if it is not on command line if parsed_args.comment is None: print "Write below the comment that you want to save in the database." print " # This is a multiline input, press CTRL+D on a" print " # empty line when you finish" try: newlines = [] while True: input_txt = raw_input() if input_txt.strip() == '?': print "\n".join([ " > {}".format(descl) for descl in "HELP: {}".format(desc).split('\n') ]) continue else: newlines.append(input_txt) except EOFError: # Ctrl+D pressed: end of input. pass the_comment = "\n".join(newlines) else: the_comment = parsed_args.comment node = load_node(parsed_args.pk) node._update_comment(the_comment, parsed_args.id, user)
def run(self, *args): """ Deletes a node and it's inferred data provenance :raise ValueError: if no valid pk or uuid is given. """ import argparse from aiida.common.exceptions import NotExistent from aiida.utils.delete_nodes import delete_nodes parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='delete a node and everything that originated from that node') parser.add_argument('pks', type=int, default=None, nargs="*", help="ID of the nodes to delete.") parser.add_argument('-u', '--uuids', default=None, nargs='*', help='The uuid of the nodes to delete') parser.add_argument('-c', '--follow-calls', help='follow the call links downwards when deleting. If a node is a WorkCalculation, will delete everything it called', action='store_true') parser.add_argument('-n', '--dry-run', help='dry run, does not delete', action='store_true') # Commenting this option for now # parser.add_argument('-f', '--force', help='force deletion, disables final user confirmation', action='store_true') # Commenting also the option for follow returns. This is dangerous for the unexperienced user. # parser.add_argument('-r', '--follow-returns', # help='follow the return-links downwards when deleting. If a node is a WorkCalculation, will delete everything it returned', # action='store_true') parser.add_argument('-v', '--verbosity', help="Verbosity level: 0: No printout; 1: Print number of nodes marked for deletion; " "2 and higher: Print individual nodes that are marked for deletion", action='count', default=1) args = list(args) parsed_args = parser.parse_args(args) if not is_dbenv_loaded(): load_dbenv() from aiida.orm import Node from aiida.orm.querybuilder import QueryBuilder filters={'or':[]} for key, req_vals in (('id', parsed_args.pks), ('uuid', parsed_args.uuids)): if req_vals: filters['or'].append({key:{'in':req_vals}}) # If neither of the arguments is passed, exit the program if not filters['or']: print "No nodes specified." return None node_pks_to_delete = set([_ for _, in QueryBuilder().append(Node, filters=filters, project='id').all()]) if not(node_pks_to_delete): print "Nothing to delete" return None delete_nodes(node_pks_to_delete, follow_calls=parsed_args.follow_calls, dry_run=parsed_args.dry_run, verbosity=parsed_args.verbosity)
def load_dbenv_if_not_loaded(**kwargs): """ load dbenv if necessary, run spinner meanwhile to show command hasn't crashed """ from aiida.backends.utils import load_dbenv, is_dbenv_loaded from aiida.backends.settings import AIIDADB_PROFILE kwargs['profile'] = kwargs.get('profile', AIIDADB_PROFILE) if not is_dbenv_loaded(): with spinner(): load_dbenv(**kwargs)
def pass_to_django_manage(argv, profile=None): """ Call the corresponding django manage.py command """ from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv(profile=profile) import django.core.management django.core.management.execute_from_command_line(argv)
def calculation_kill(self, *args): """ Kill a calculation. Pass a list of calculation PKs to kill them. If you also pass the -f option, no confirmation will be asked. """ if not is_dbenv_loaded(): load_dbenv() from aiida.cmdline import wait_for_confirmation from aiida.orm.calculation.job import JobCalculation as Calc from aiida.common.exceptions import NotExistent, InvalidOperation, \ RemoteOperationError import argparse parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Kill AiiDA calculations.') parser.add_argument( 'calcs', metavar='PK', type=int, nargs='+', help='The principal key (PK) of the calculations to kill') parser.add_argument('-f', '--force', help='Force the kill of calculations', action="store_true") args = list(args) parsed_args = parser.parse_args(args) if not parsed_args.force: sys.stderr.write( "Are you sure to kill {} calculation{}? [Y/N] ".format( len(parsed_args.calcs), "" if len(parsed_args.calcs) == 1 else "s")) if not wait_for_confirmation(): sys.exit(0) counter = 0 for calc_pk in parsed_args.calcs: try: c = load_node(calc_pk, parent_class=Calc) c.kill() # Calc.kill(calc_pk) counter += 1 except NotExistent: print >> sys.stderr, ("WARNING: calculation {} " "does not exist.".format(calc_pk)) except (InvalidOperation, RemoteOperationError) as e: print >> sys.stderr, (e.message) print >> sys.stderr, "{} calculation{} killed.".format( counter, "" if counter == 1 else "s")
def computer_setup(self, *args): """ Setup a new or existing computer """ import readline if len(args) != 0: print >> sys.stderr, ("after 'computer setup' there cannot be any " "argument.") sys.exit(1) if not is_dbenv_loaded(): load_dbenv() from aiida.common.exceptions import NotExistent, ValidationError from aiida.orm.computer import Computer as AiidaOrmComputer print "At any prompt, type ? to get some help." print "---------------------------------------" # get the new computer name readline.set_startup_hook(lambda: readline.insert_text(previous_value)) input_txt = raw_input("=> Computer name: ") if input_txt.strip() == '?': print "HELP:", "The computer name" computer_name = input_txt.strip() try: computer = self.get_computer(name=computer_name) print "A computer called {} already exists.".format(computer_name) print "Use 'verdi computer update' to update it, and be careful if" print "you really want to modify a database entry!" print "Now exiting..." sys.exit(1) except NotExistent: computer = AiidaOrmComputer(name=computer_name) print "Creating new computer with name '{}'".format(computer_name) prompt_for_computer_configuration(computer) try: computer.store() except ValidationError as e: print "Unable to store the computer: {}. Exiting...".format( e.message) sys.exit(1) print "Computer '{}' successfully stored in DB.".format(computer_name) print "pk: {}, uuid: {}".format(computer.pk, computer.uuid) print "Note: before using it with AiiDA, configure it using the command" print " verdi computer configure {}".format(computer_name) print "(Note: machine_dependent transport parameters cannot be set via " print "the command-line interface at the moment)"
def comment_show(self, *args): """ Show the comments of a node """ import argparse from aiida.backends.utils import get_automatic_user if not is_dbenv_loaded(): load_dbenv() user = get_automatic_user() parser = argparse.ArgumentParser( prog=self.get_full_command_name(), description='Show the comments of a node in the database.') parser.add_argument('-u', '--user', type=str, default=None, help='Show only the comments of a given user (optional).') parser.add_argument('pk', metavar='PK', type=int, help='The pk (an integer) of the node.') parser.add_argument('id', metavar='ID', type=int, default=None, nargs='?', help='The id (an integer) of the comment.') # Note that this is a false description, I'm using the DBComment.pk parsed_args = parser.parse_args(args) node = load_node(parsed_args.pk) all_comments = node.get_comments(pk=parsed_args.id) if parsed_args.user is not None: to_print = [i for i in all_comments if i['user__email'] == parsed_args.user] if not to_print: print "Nothing found for user '{}'.".format(parsed_args.user) print "Valid users found for Node {} are: {}.".format(parsed_args.pk, ", ".join(set( ["'" + i['user__email'] + "'" for i in all_comments]))) else: to_print = all_comments if parsed_args.id is not None: to_print = [i for i in to_print if i['pk'] == parsed_args.id] for i in to_print: print "***********************************************************" print "Comment of '{}' on {}".format(i['user__email'], i['ctime'].strftime("%Y-%m-%d %H:%M")) print "ID: {}. Last modified on {}".format(i['pk'], i['mtime'].strftime("%Y-%m-%d %H:%M")) print "" print "{}".format(i['content']) print "" # If there is nothing to print, print a message if not to_print: print "No comment found."
from aiida.backends.utils import load_dbenv, is_dbenv_loaded if not is_dbenv_loaded(): load_dbenv() from aiida.orm import load_node from aiida.orm.utils import DataFactory from aiida.workflows2.db_types import Float, Str, NumericType, SimpleData from aiida.orm.code import Code from aiida.orm.data.structure import StructureData from aiida.workflows2.run import run from aiida.workflows2.fragmented_wf import FragmentedWorkfunction, \ ResultToContext, while_ from aiida.workflows2.wf import wf from common_wf import generate_scf_input_params from create_rescale import rescale, create_diamond_fcc from aiida.orm.calculation.job.quantumespresso.pw import PwCalculation GPa_to_eV_over_ang3 = 1./160.21766208 # Set up the factories ParameterData = DataFactory("parameter") KpointsData = DataFactory("array.kpoints") PwProcess = PwCalculation.process() def get_first_deriv(stress): """ Return the energy first derivative from the stress """ from numpy import trace