Beispiel #1
0
def _one_day(args):
    if not args:
        return
    cwd = os.getcwd()
    for a in args:
        img = os.path.basename(a)
        d = os.path.dirname(a)
        if d:
            os.chdir(d)
        if not os.path.exists(img):
            continue
        if common.MOVIE_SUFFIX.search(img):
            subprocess.check_call(['open', '-a', 'QuickTime Player.app', img])
        else:
            subprocess.check_call(['open', '-a', 'Preview.app', img])
        msg = six.raw_input(a + ': ')
        if not msg:
            status = False
            break
        if os.path.exists(img):
            if msg == '!':
                os.remove(img)
                print(a + ': removed')
            else:
                with open('index.txt', 'a') as f:
                    f.write(img + ' ' + msg + '\n')
        else:
            print(a + ': does not exist')
        if d:
            os.chdir(cwd)
    try:
        os.remove('index.txt~')
    except Exception:
        pass
    return
Beispiel #2
0
    def concatenate(self, jobfolder):
        """ Updates content of current job-folder with that of another.

            :param jobfolder:
              :py:class:`JobFolder` instance, or :py:class:`JobParams` instance with
              which to update the current job-folder.

            Update means that jobs and jobparameters will be overwritten with those
            from the input. Jobs in the input which are not in the current
            job-folder will be overwritten. If `jobfolder` is a
            :py:class:`JobFolder` instance, it is possible to use wildcards in order
            to select those jobs of interests.

            .. warning: New jobs are always added at the root of the job-folder.
              Make sure the jobs bear the names you want.
        """
        import six
        from .jobfolder import JobFolder
        from .. import is_interactive
        keys = jobfolder.keys()
        if is_interactive:
            if len(keys) == 0:
                print("Empty input job-folder. Aborting.")
                return
            add = [k for k in keys if k in self]
            if len(add) > 0:
                print("Adding the following jobfolderionaries:")
                for key in add:
                    print(key)
            update = [k for k in keys if k in self]
            if len(update) > 0:
                print("Updating the following jobfolderionaries:")
                for key in update:
                    print(key)
            a = ''
            while a != 'n' and a != 'y':
                a = six.raw_input("Is the above OK? [n/y] ")
            if a == 'n':
                print("Aborting.")
                return
        rootadd = jobfolder
        if isinstance(rootadd, JobParams):
            rootadd = JobFolder()
            for key in keys:
                job = rootadd / key
                rootadd[key] = jobfolder.jobfolder[key]

        self.jobfolder.root.update(rootadd)
Beispiel #3
0
    def __setitem__(self, name, jobfolder):
        """ Modifies/creates item in job-folder.

            :param str name: 
              Name of item to modify.
            :param jobfolder:
              :py:class:`JobFolder pylada.jobs.jobfolder.JobDict` or
              :py:class:`JobParams` with which to set/modify item.
              In the latter case, it should point to a single entry in the
              job-folder. Eg no wildcards.

            This function provides the ability to extend a job-folder with other jobs.

            >>> jobparams['newjob'] = jobparams['oldjob'] 
            >>> jobparams['newjob'] = some_job_dictionary

            In  both cases above, the left-hand-side cannot be a wildcard.
            Similarly, in the first case above, the right hand side should also point to
            a valid job, not a sequence of jobs:

            >>> jobparams['newjobs'] = jobparams['*/oldjobs']
            raises KeyError
            >>> jobparams['*/newjobs'] = jobparams['oldjobs']
            No Error! creates a job called '*/newjobs'

            .. warning:: The right-hand-side is *always* deep-copied_.
              .. _deep-copied:: http://docs.python.org/library/copy.html
        """
        import six
        from .. import is_interactive
        from copy import deepcopy

        if isinstance(jobfolder, JobParams):
            try:
                jobfolder = jobfolder.jobfolder[jobfolder.view]
            except KeyError:
                raise KeyError("{0} is not an actual folder".format(
                    jobfolder.view))
        if name in self.jobfolder and is_interactive:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input(
                    "Modifying existing folder parameters {0}.\nIs this OK? [y/n] "
                    .format(name))
            if a == 'n':
                print("Aborting.")
                return
        self.jobfolder[name] = deepcopy(jobfolder)
Beispiel #4
0
    def concatenate(self, jobfolder):
        """ Updates content of current job-folder with that of another.

            :param jobfolder:
              :py:class:`JobFolder` instance, or :py:class:`JobParams` instance with
              which to update the current job-folder.

            Update means that jobs and jobparameters will be overwritten with those
            from the input. Jobs in the input which are not in the current
            job-folder will be overwritten. If `jobfolder` is a
            :py:class:`JobFolder` instance, it is possible to use wildcards in order
            to select those jobs of interests.

            .. warning: New jobs are always added at the root of the job-folder.
              Make sure the jobs bear the names you want.
        """
        import six
        from .jobfolder import JobFolder
        from .. import is_interactive
        keys = jobfolder.keys()
        if is_interactive:
            if len(keys) == 0:
                print("Empty input job-folder. Aborting.")
                return
            add = [k for k in keys if k in self]
            if len(add) > 0:
                print("Adding the following jobfolderionaries:")
                for key in add:
                    print(key)
            update = [k for k in keys if k in self]
            if len(update) > 0:
                print("Updating the following jobfolderionaries:")
                for key in update:
                    print(key)
            a = ''
            while a != 'n' and a != 'y':
                a = six.raw_input("Is the above OK? [n/y] ")
            if a == 'n':
                print("Aborting.")
                return
        rootadd = jobfolder
        if isinstance(rootadd, JobParams):
            rootadd = JobFolder()
            for key in keys:
                job = rootadd / key
                rootadd[key] = jobfolder.jobfolder[key]

        self.jobfolder.root.update(rootadd)
Beispiel #5
0
 def __delitem__(self, name):
     """ Deletes items from job-folder. """
     import six
     from .. import is_interactive
     if is_interactive:
         print("Deleting the following jobs:")
         for key in self[name].keys():
             print(key)
         a = ''
         while a != 'n' and a != 'y':
             a = six.raw_input('Ok? [y/n] ')
         if a == 'n':
             print("Aborting.")
             return
     for key in self[name].keys():
         del self.jobfolder.root[key]
Beispiel #6
0
 def __delitem__(self, name):
     """ Deletes items from job-folder. """
     import six
     from .. import is_interactive
     if is_interactive:
         print("Deleting the following jobs:")
         for key in self[name].keys():
             print(key)
         a = ''
         while a != 'n' and a != 'y':
             a = six.raw_input('Ok? [y/n] ')
         if a == 'n':
             print("Aborting.")
             return
     for key in self[name].keys():
         del self.jobfolder.root[key]
Beispiel #7
0
    def __setitem__(self, name, jobfolder):
        """ Modifies/creates item in job-folder.

            :param str name: 
              Name of item to modify.
            :param jobfolder:
              :py:class:`JobFolder pylada.jobs.jobfolder.JobDict` or
              :py:class:`JobParams` with which to set/modify item.
              In the latter case, it should point to a single entry in the
              job-folder. Eg no wildcards.

            This function provides the ability to extend a job-folder with other jobs.

            >>> jobparams['newjob'] = jobparams['oldjob'] 
            >>> jobparams['newjob'] = some_job_dictionary

            In  both cases above, the left-hand-side cannot be a wildcard.
            Similarly, in the first case above, the right hand side should also point to
            a valid job, not a sequence of jobs:

            >>> jobparams['newjobs'] = jobparams['*/oldjobs']
            raises KeyError
            >>> jobparams['*/newjobs'] = jobparams['oldjobs']
            No Error! creates a job called '*/newjobs'

            .. warning:: The right-hand-side is *always* deep-copied_.
              .. _deep-copied:: http://docs.python.org/library/copy.html
        """
        import six
        from .. import is_interactive
        from copy import deepcopy

        if isinstance(jobfolder, JobParams):
            try:
                jobfolder = jobfolder.jobfolder[jobfolder.view]
            except KeyError:
                raise KeyError("{0} is not an actual folder".format(jobfolder.view))
        if name in self.jobfolder and is_interactive:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input(
                    "Modifying existing folder parameters {0}.\nIs this OK? [y/n] ".format(name))
            if a == 'n':
                print("Aborting.")
                return
        self.jobfolder[name] = deepcopy(jobfolder)
Beispiel #8
0
    def qdel(self, arg):
        """ Cancel jobs which grep for whatever is in arg.

            For instance, the following cancels all jobs with "anti-ferro" in
            their name. The name is the last column in qstat.

            >>> %qdel "anti-ferro"
        """
        import six
        import pylada
        from pylada import qdel_exe

        if not hasattr(pylada, 'ipython_qstat'):
            raise RuntimeError(
                "Missing ipython_qstat function: cannot use %qdel")

        arg = arg.lstrip().rstrip()
        if '--help' in arg.split() or '-h' in arg.split():
            print(self.qdel.__doc__)
            return

        if not arg:
            result = self.qstat(arg)
            if not result:
                print('No jobs in queue')
                return
            for name in result.fields(-1):
                print("cancelling %s." % (name))
                message = "Are you sure you want to cancel"\
                    "the jobs listed above? [y/n] "
        else:
            message = "Cancel all jobs? [y/n] "
            key = ''
            while key not in ['n', 'y']:
                key = six.raw_input(message)
                if key == 'n':
                    return

        result = self.qstat(arg)
        for i, name in zip(result.fields(0), result.fields(-1)):
            # xxx use subprocess
            self.shell.system('{0} {1}'.format(qdel_exe, i))
Beispiel #9
0
def copy_folder(self, event):
    """ Copies a jobfolder somewhere. 


        Emulates bash's ``cp`` command. By default, it only copies one job.
        However, it can be made to copy a full tree as well, using the ``-r``
        directive.  When it finds it would overwrite a non-empty jobfolder, it
        prompts the user interactively, unless the '-f' directive is given.


        >>> copyfolder thisjob thatjob

        Copies ``thisjob`` to ``thatjob``, but not the subfolders of ``thisjob``.

        By default, the jobfolders are deepcopied. This means that the none of
        the arguments or functionals of the current job are shared by the copied
        jobs. However, the relation-ships between the current jobs are retained
        in the destinations. In other words, if jobs 'JobA' and 'JobA/JobB' share
        the same 'structure' variable object and they are copied to 'JobC' (with
        '-r'), then two new subfolders are created, 'JobC/JobA'
        and'JobC/JobA/JobB'. Both of these subfolders will share a reference to
        the same `structure` object.  However their `structure` object is
        different from that of the original `JobA` and `JobB`. This feature can
        be turned off with the option `--nodeepcopy` (in which case, `structure`
        would be shared by all source and destination folders). Furthermore, if
        '--nodeepcopy' is used, then the functionals are shared between source
        and destination.
    """
    import six
    from argparse import ArgumentParser
    from os.path import join, normpath, relpath
    from copy import deepcopy
    from ..interactive import jobfolder as cjf

    parser = ArgumentParser(
        prog='%copyfolder',
        description='Copies a jobfolder from one location to another')
    parser.add_argument('-f',
                        '--force',
                        action='store_true',
                        dest='force',
                        help='Does not prompt when overwriting a job-folder.')
    parser.add_argument('-r',
                        '--recursive',
                        action='store_true',
                        dest='recursive',
                        help='Whether to copy subfolders as well.')
    parser.add_argument('--nodeepcopy',
                        action='store_true',
                        help='Destination folders will share the parameters '
                        'from the original folders.')
    parser.add_argument('source',
                        type=str,
                        metavar='SOURCE',
                        help='Jobfolder to copy')
    parser.add_argument('destination',
                        type=str,
                        metavar='DESTINATION',
                        help='Destination folder')

    try:
        args = parser.parse_args(event.split())
    except SystemExit:
        return None

    shell = get_ipython()

    # gets current folder.
    if 'jobparams' not in shell.user_ns:
        print('No jobfolder currently loaded.')
        return
    jobparams = shell.user_ns['jobparams']

    # normalize destination.
    if args.destination[0] != ['/']:
        destination = normpath(join(cjf.name, args.destination))
        if destination[0] != '/':
            print('Incorrect destination', destination)
            return
    else:
        destination = normpath(args.destination)

    # create list of source directories
    if args.source[0] != ['/']:
        source = normpath(join(cjf.name, args.source))
        if source[0] != '/':
            print('Incorrect source', source)
            return
    else:
        source = normpath(args.source)
    if source not in cjf:
        print('Source', source, 'does not exist')
        return
    if destination == source:
        print('Source and destination are the same')
        return
    rootsource = source
    pairs = []
    if cjf[rootsource].is_executable and not cjf[rootsource].is_tagged:
        pairs = [(source, relpath(destination, rootsource))]
    if args.recursive:
        for source in jobparams[rootsource]:
            if not cjf[source].is_executable:
                continue
            if cjf[source].is_tagged:
                continue
            pairs.append((source, join(destination,
                                       relpath(source, rootsource))))
    if len(pairs) == 0:
        print("Nothing to copy.")
        return

    # now performs actual copy
    root = deepcopy(cjf.root) if not args.nodeepcopy else cjf.root
    for source, destination in pairs:
        # gets the jobfolder source.
        jobsource = root[source]
        # gets the jobfolder destination.
        jobdest = cjf
        for name in destination.split('/'):
            jobdest = jobdest / name
        # something already exists here
        if jobdest.is_executable and not args.force:
            print('Copying', jobsource.name, 'to', jobdest.name)
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input(
                    '{0} already exists. Overwrite? [y/n]'.format(
                        jobdest.name))
            if a == 'n':
                print(jobdest.name, 'not overwritten.')
                continue
        # now copies folder items.
        for key, value in jobdest.__dict__.items():
            if key not in ['children', 'parent', 'param']:
                jobdest.__dict__[key] = value
        jobdest._functional = jobsource._functional
        jobdest.params = jobsource.params.copy()
Beispiel #10
0
def delete_folder(self, event):
    """ Deletes a job-folder.

        By default, only the job itself is delete. If there are no sub-folders,
        then jobfolder itself is also deleted. Suppose we have a jobfolder
        '/JobA' and '/JobA/JobB' and both contain actual jobs. 

        >>> deletefolder /JobA

        This would remove the job-parameters from 'JobA' but leave '/JobA/JobB'
        unscathed. However, 

        >>> deletefolder /JobA/JobB

        will remove the branch 'JobB' completely, since there are no sub-folders
        there.

        It is also possible to remove all folders of a branch recursively:

        >>> deletefolder -r /JobA

        This will now remove JobA and all its subfolders.

        .. warning::

          This magic function does not check whether job-folders are 'on' or
          'off'. The recursive option should be used with care.
    """
    import six
    from argparse import ArgumentParser
    from os.path import join, normpath
    from ..interactive import jobfolder as cjf

    parser = ArgumentParser(prog='%deletefolder',
                            description='Deletes a job-folder.')
    parser.add_argument('-f',
                        '--force',
                        action='store_true',
                        dest='force',
                        help='Does not prompt before deleting folders.')
    parser.add_argument('-r',
                        '--recursive',
                        action='store_true',
                        dest='recursive',
                        help='Whether to delete subfolders as well.')
    parser.add_argument('folder',
                        type=str,
                        metavar='JOBFOLDER',
                        help='Jobfolder to delete')

    try:
        args = parser.parse_args(event.split())
    except SystemExit:
        return None

    shell = get_ipython()

    # normalize  folders to delete
    if args.folder[0] != ['/']:
        folder = normpath(join(cjf.name, args.folder))
    else:
        folder = normpath(args.folder)
    if folder not in cjf:
        print("Folder", folder, "does not exist.")
        return
    # deletes jobfolder recursively.
    if args.recursive:
        if not args.force:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input(
                    "Delete {0} and its subfolders? [y/n]".format(
                        cjf[folder].name))
            if a == 'n':
                print(cjf[folder].name, "not deleted.")
                return
        jobfolder = cjf[folder]
        if jobfolder.parent is None:
            jobfolder = jobfolder.parent
            jobfolder._functional = None
            jobfolder.children = {}
            jobfolder.params = {}
        else:
            del jobfolder.parent[jobfolder.name.split('/')[-2]]
    # only delete specified jobfolder.
    else:
        if not args.force:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input("Delete {0}? [y/n]".format(cjf[folder].name))
            if a == 'n':
                print(cjf[folder].name, "not deleted.")
                return
        jobfolder = cjf[folder]
        if len(jobfolder.children) == 0 and jobfolder.parent is not None:
            del jobfolder.parent[jobfolder.name.split('/')[-2]]
        else:
            jobfolder._functional = None
            jobfolder.params = {}
Beispiel #11
0
def copy_folder(self, event):
    """ Copies a jobfolder somewhere. 


        Emulates bash's ``cp`` command. By default, it only copies one job.
        However, it can be made to copy a full tree as well, using the ``-r``
        directive.  When it finds it would overwrite a non-empty jobfolder, it
        prompts the user interactively, unless the '-f' directive is given.


        >>> copyfolder thisjob thatjob

        Copies ``thisjob`` to ``thatjob``, but not the subfolders of ``thisjob``.

        By default, the jobfolders are deepcopied. This means that the none of
        the arguments or functionals of the current job are shared by the copied
        jobs. However, the relation-ships between the current jobs are retained
        in the destinations. In other words, if jobs 'JobA' and 'JobA/JobB' share
        the same 'structure' variable object and they are copied to 'JobC' (with
        '-r'), then two new subfolders are created, 'JobC/JobA'
        and'JobC/JobA/JobB'. Both of these subfolders will share a reference to
        the same `structure` object.  However their `structure` object is
        different from that of the original `JobA` and `JobB`. This feature can
        be turned off with the option `--nodeepcopy` (in which case, `structure`
        would be shared by all source and destination folders). Furthermore, if
        '--nodeepcopy' is used, then the functionals are shared between source
        and destination.
    """
    import six
    from argparse import ArgumentParser
    from os.path import join, normpath, relpath
    from copy import deepcopy
    from ..interactive import jobfolder as cjf

    parser = ArgumentParser(prog='%copyfolder',
                            description='Copies a jobfolder from one location to another')
    parser.add_argument('-f', '--force', action='store_true', dest='force',
                        help='Does not prompt when overwriting a job-folder.')
    parser.add_argument('-r', '--recursive', action='store_true',
                        dest='recursive', help='Whether to copy subfolders as well.')
    parser.add_argument('--nodeepcopy', action='store_true',
                        help='Destination folders will share the parameters '
                        'from the original folders.')
    parser.add_argument('source', type=str, metavar='SOURCE',
                        help='Jobfolder to copy')
    parser.add_argument('destination', type=str, metavar='DESTINATION',
                        help='Destination folder')

    try:
        args = parser.parse_args(event.split())
    except SystemExit:
        return None

    shell = get_ipython()

    # gets current folder.
    if 'jobparams' not in shell.user_ns:
        print('No jobfolder currently loaded.')
        return
    jobparams = shell.user_ns['jobparams']

    # normalize destination.
    if args.destination[0] != ['/']:
        destination = normpath(join(cjf.name, args.destination))
        if destination[0] != '/':
            print('Incorrect destination', destination)
            return
    else:
        destination = normpath(args.destination)

    # create list of source directories
    if args.source[0] != ['/']:
        source = normpath(join(cjf.name, args.source))
        if source[0] != '/':
            print('Incorrect source', source)
            return
    else:
        source = normpath(args.source)
    if source not in cjf:
        print('Source', source, 'does not exist')
        return
    if destination == source:
        print('Source and destination are the same')
        return
    rootsource = source
    pairs = []
    if cjf[rootsource].is_executable and not cjf[rootsource].is_tagged:
        pairs = [(source, relpath(destination, rootsource))]
    if args.recursive:
        for source in jobparams[rootsource]:
            if not cjf[source].is_executable:
                continue
            if cjf[source].is_tagged:
                continue
            pairs.append((source, join(destination, relpath(source, rootsource))))
    if len(pairs) == 0:
        print("Nothing to copy.")
        return

    # now performs actual copy
    root = deepcopy(cjf.root) if not args.nodeepcopy else cjf.root
    for source, destination in pairs:
        # gets the jobfolder source.
        jobsource = root[source]
        # gets the jobfolder destination.
        jobdest = cjf
        for name in destination.split('/'):
            jobdest = jobdest / name
        # something already exists here
        if jobdest.is_executable and not args.force:
            print('Copying', jobsource.name, 'to', jobdest.name)
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input('{0} already exists. Overwrite? [y/n]'.format(jobdest.name))
            if a == 'n':
                print(jobdest.name, 'not overwritten.')
                continue
        # now copies folder items.
        for key, value in jobdest.__dict__.items():
            if key not in ['children', 'parent', 'param']:
                jobdest.__dict__[key] = value
        jobdest._functional = jobsource._functional
        jobdest.params = jobsource.params.copy()
Beispiel #12
0
def delete_folder(self, event):
    """ Deletes a job-folder.

        By default, only the job itself is delete. If there are no sub-folders,
        then jobfolder itself is also deleted. Suppose we have a jobfolder
        '/JobA' and '/JobA/JobB' and both contain actual jobs. 

        >>> deletefolder /JobA

        This would remove the job-parameters from 'JobA' but leave '/JobA/JobB'
        unscathed. However, 

        >>> deletefolder /JobA/JobB

        will remove the branch 'JobB' completely, since there are no sub-folders
        there.

        It is also possible to remove all folders of a branch recursively:

        >>> deletefolder -r /JobA

        This will now remove JobA and all its subfolders.

        .. warning::

          This magic function does not check whether job-folders are 'on' or
          'off'. The recursive option should be used with care.
    """
    import six
    from argparse import ArgumentParser
    from os.path import join, normpath
    from ..interactive import jobfolder as cjf

    parser = ArgumentParser(prog='%deletefolder',
                            description='Deletes a job-folder.')
    parser.add_argument('-f', '--force', action='store_true', dest='force',
                        help='Does not prompt before deleting folders.')
    parser.add_argument('-r', '--recursive', action='store_true',
                        dest='recursive', help='Whether to delete subfolders as well.')
    parser.add_argument('folder', type=str, metavar='JOBFOLDER',
                        help='Jobfolder to delete')

    try:
        args = parser.parse_args(event.split())
    except SystemExit:
        return None

    shell = get_ipython()

    # normalize  folders to delete
    if args.folder[0] != ['/']:
        folder = normpath(join(cjf.name, args.folder))
    else:
        folder = normpath(args.folder)
    if folder not in cjf:
        print("Folder", folder, "does not exist.")
        return
    # deletes jobfolder recursively.
    if args.recursive:
        if not args.force:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input("Delete {0} and its subfolders? [y/n]".format(cjf[folder].name))
            if a == 'n':
                print(cjf[folder].name, "not deleted.")
                return
        jobfolder = cjf[folder]
        if jobfolder.parent is None:
            jobfolder = jobfolder.parent
            jobfolder._functional = None
            jobfolder.children = {}
            jobfolder.params = {}
        else:
            del jobfolder.parent[jobfolder.name.split('/')[-2]]
    # only delete specified jobfolder.
    else:
        if not args.force:
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input("Delete {0}? [y/n]".format(cjf[folder].name))
            if a == 'n':
                print(cjf[folder].name, "not deleted.")
                return
        jobfolder = cjf[folder]
        if len(jobfolder.children) == 0 and jobfolder.parent is not None:
            del jobfolder.parent[jobfolder.name.split('/')[-2]]
        else:
            jobfolder._functional = None
            jobfolder.params = {}
Beispiel #13
0
def export(self, event):
    """ Tars files from a calculation.  """
    import six
    import argparse
    import tarfile
    from os import getcwd
    from os.path import exists, isfile, extsep, relpath, dirname, join
    from glob import iglob
    from ..misc import RelativePath
    from .. import interactive
    from . import get_shell
    shell = get_shell(self)

    parser = argparse.ArgumentParser(prog='%export',
                                     description='Exports input/output files from current job-folder. '
                                     'Depending on the extension of FILE, this will create '
                                     'a simple tar file, or a compressed tar file. Using the '
                                     'option --list, one can also obtain a list of all files '
                                     'which would go in the tar archive. '
                                     'Finally, this function only requires the \"collect\" '
                                     'exists in the usernamespace. It may have been declared '
                                     'from loading a job-folder using \"explore\", or directly '
                                     'with \"collect = vasp.MassExtract()\".')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--list', action="store_true", dest="aslist",
                       help='Do not tar, return a list of all the files.')
    group.add_argument('filename', metavar='FILE', type=str,
                       default='export.tar.gz', nargs='?',
                       help='Path to the tarfile. Suffixes ".gz" and ".tgz" indicate '
                       'gzip compression, whereas ".bz" and ".bz2" indicate bzip '
                       'compression. Otherwise, no compression is used.')
    parser.add_argument('--input', action="store_true", dest="input",
                        help='Include input (INCAR/crystal.d12) files.')
    parser.add_argument('--dos', action="store_true", dest="dos",
                        help='Include Density of States (DOSCAR) files.')
    parser.add_argument('--structure', action="store_true", dest="structure",
                        help='Include structure input (POSCAR) files.')
    parser.add_argument('--charge', action="store_true", dest="charge",
                        help='Include charge (CHGCAR) files.')
    parser.add_argument('--contcar', action="store_true", dest="contcar",
                        help='Include CONTCAR files.')
    parser.add_argument('--wavefunctions', action="store_true", dest="wavefunctions",
                        help='Include wavefunctions (WAVECAR/crystal.98) files.')
    parser.add_argument('--procar', action="store_true", dest="procar",
                        help='Include PROCAR files.')
    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--down', action="store_true", dest="down",
                       help='Tar from one directory down.')
    group.add_argument('--from', type=str, dest="dir", default=None,
                       help='Root directory from which to give filenames. '
                       'Defaults to current working directory.')
    group.add_argument('--with', type=str, dest="others", nargs='*',
                       help='Adds pattern or filename to files to export.'
                       'Any file in any visited directory matching the given pattern '
                       'will be added to the archive. This options can be given more than '
                       'once if different file patterns are required.')

    try:
        args = parser.parse_args(event.split())
    except SystemExit as e:
        return None

    collect = shell.user_ns.get('collect', None)
    rootpath = getattr(collect, 'rootpath', None)
    if collect is None:
        print("Could not find 'collect' object in user namespace.")
        print("Please load a job-dictionary.")
        return

    kwargs = args.__dict__.copy()
    kwargs.pop('filename', None)

    if rootpath is None:
        if hasattr(shell.user_ns.get('collect', None), 'rootpath'):
            rootpath = shell.user_ns.get('collect').rootpath
    directory = getcwd() if rootpath is None else dirname(rootpath)

    if args.down:
        directory = join(directory, '..')
    elif args.dir is not None:
        directory = RelativePath(args.dir).path

    # set of directories visited.
    directories = set()
    # set of files to tar
    allfiles = set()
    for file in collect.files(**kwargs):
        allfiles.add(file)
        directories.add(dirname(file))
    # adds files from "with" argument.
    if hasattr(args.others, "__iter__"):
        for pattern in args.others:
            for dir in directories:
                for sfile in iglob(join(dir, pattern)):
                    if exists(sfile) and isfile(sfile):
                        allfiles.add(sfile)
    # adds current job folder.
    if interactive.jobfolder_path is not None:
        if isfile(interactive.jobfolder_path):
            allfiles.add(interactive.jobfolder_path)

    # now tar or list files.
    if args.aslist:
        from IPython.utils.text import SList
        directory = getcwd()
        return SList([relpath(file, directory) for file in allfiles])
    else:
        # get filename of tarfile.
        args.filename = relpath(RelativePath(args.filename).path, getcwd())
        if exists(args.filename):
            if not isfile(args.filename):
                print("{0} exists but is not a file. Aborting.".format(args.filename))
                return
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input("File {0} already exists.\nOverwrite? [y/n] "
                                  .format(args.filename))
            if a == 'n':
                print("Aborted.")
                return

        # figure out the type of the tarfile.
        if args.filename.find(extsep) == -1:
            endname = ''
        else:
            endname = args.filename[-args.filename[::-1].find(extsep) - 1:][1:]
        if endname in ['gz', 'tgz']:
            tarme = tarfile.open(args.filename, 'w:gz')
        elif endname in ['bz', 'bz2']:
            tarme = tarfile.open(args.filename, 'w:bz2')
        else:
            tarme = tarfile.open(args.filename, 'w')
        for file in allfiles:
            tarme.add(file, arcname=relpath(file, directory))
        tarme.close()
        print("Saved archive to {0}.".format(args.filename))
Beispiel #14
0
def savefolders(self, event):
    """ Saves job-folder to disk.

        This function can be called in one of three ways:

        >>> savefolders filename.dict rootfolder 

        In this case, "filename.dict" is a file where to save the jobfolder
        "rootfolder". The latter must be a python variable, not another filename.
        The current job-folder becomes "rootfolder", and the current path 


        >>> savefolders filename.dict

        Saves the current job-folder to "filename.dict". Fails if no current
        job-folder.

        >>> savefolders 

        Saves the current job-folder to the current job-folder path. Fails if
        either are unknown.
    """
    import six
    from os.path import exists, isfile
    from ..jobfolder import JobParams, MassExtract as Collect, save
    from .. import interactive
    from ..misc import RelativePath
    from . import get_shell

    shell = get_shell(self)

    args = [u for u in event.split()]
    if "--help" in args or "-h" in args:
        print(savefolders.__doc__)
        return

    if len(args) > 2:
        print("savefolders takes zero, one, or two arguments.")
        return

    if len(args) == 2:
        from .explore import explore

        explore(self, args[1])
        savefolders(self, args[0])
        return

    if interactive.jobfolder is None:
        print("No current job-folder.")
        print("Please load first with %explore.")
        return
    jobfolder = interactive.jobfolder.root
    jobfolder_path = interactive.jobfolder_path

    if len(args) == 1:
        jobfolder_path = RelativePath(args[0]).path
        interactive.jobfolder_path = jobfolder_path

    if jobfolder_path is None:
        print("No current job-folder path.\n" "Please specify on input, eg\n" ">saveto this/path/filename")
        return
    if exists(jobfolder_path):
        if not isfile(jobfolder_path):
            print("{0} is not a file.".format(jobfolder_path))
            return
        a = "y"  # testValidProgram: force yes to allow automated testing
        while a not in ["n", "y"]:
            a = six.raw_input("File %s already exists.\nOverwrite? [y/n] " % jobfolder_path)
        if a == "n":
            print("Aborting.")
            return
    save(jobfolder.root, jobfolder_path, overwrite=True, timeout=10)
    if len(args) == 1:
        if "collect" not in shell.user_ns:
            shell.user_ns["collect"] = Collect(dynamic=True, path=jobfolder_path)
        if "jobparams" not in shell.user_ns:
            shell.user_ns["jobparams"] = JobParams()
Beispiel #15
0
def savefolders(self, event):
    """ Saves job-folder to disk.

        This function can be called in one of three ways:

        >>> savefolders filename.dict rootfolder 

        In this case, "filename.dict" is a file where to save the jobfolder
        "rootfolder". The latter must be a python variable, not another filename.
        The current job-folder becomes "rootfolder", and the current path 


        >>> savefolders filename.dict

        Saves the current job-folder to "filename.dict". Fails if no current
        job-folder.

        >>> savefolders 

        Saves the current job-folder to the current job-folder path. Fails if
        either are unknown.
    """
    import six
    from os.path import exists, isfile
    from ..jobfolder import JobParams, MassExtract as Collect, save
    from .. import interactive
    from ..misc import RelativePath
    from . import get_shell

    shell = get_shell(self)

    args = [u for u in event.split()]
    if '--help' in args or '-h' in args:
        print(savefolders.__doc__)
        return

    if len(args) > 2:
        print("savefolders takes zero, one, or two arguments.")
        return

    if len(args) == 2:
        from .explore import explore
        explore(self, args[1])
        savefolders(self, args[0])
        return

    if interactive.jobfolder is None:
        print("No current job-folder.")
        print("Please load first with %explore.")
        return
    jobfolder = interactive.jobfolder.root
    jobfolder_path = interactive.jobfolder_path

    if len(args) == 1:
        jobfolder_path = RelativePath(args[0]).path
        interactive.jobfolder_path = jobfolder_path

    if jobfolder_path is None:
        print("No current job-folder path.\n"\
              "Please specify on input, eg\n"\
              ">saveto this/path/filename")
        return
    if exists(jobfolder_path):
        if not isfile(jobfolder_path):
            print("{0} is not a file.".format(jobfolder_path))
            return
        a = 'y'  # testValidProgram: force yes to allow automated testing
        while a not in ['n', 'y']:
            a = six.raw_input("File %s already exists.\nOverwrite? [y/n] " %
                              jobfolder_path)
        if a == 'n':
            print("Aborting.")
            return
    save(jobfolder.root, jobfolder_path, overwrite=True, timeout=10)
    if len(args) == 1:
        if "collect" not in shell.user_ns:
            shell.user_ns["collect"] = Collect(dynamic=True,
                                               path=jobfolder_path)
        if "jobparams" not in shell.user_ns:
            shell.user_ns["jobparams"] = JobParams()
Beispiel #16
0
def export(self, event):
    """ Tars files from a calculation.  """
    import six
    import argparse
    import tarfile
    from os import getcwd
    from os.path import exists, isfile, extsep, relpath, dirname, join
    from glob import iglob
    from ..misc import RelativePath
    from .. import interactive
    from . import get_shell
    shell = get_shell(self)

    parser = argparse.ArgumentParser(
        prog='%export',
        description='Exports input/output files from current job-folder. '
        'Depending on the extension of FILE, this will create '
        'a simple tar file, or a compressed tar file. Using the '
        'option --list, one can also obtain a list of all files '
        'which would go in the tar archive. '
        'Finally, this function only requires the \"collect\" '
        'exists in the usernamespace. It may have been declared '
        'from loading a job-folder using \"explore\", or directly '
        'with \"collect = vasp.MassExtract()\".')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--list',
                       action="store_true",
                       dest="aslist",
                       help='Do not tar, return a list of all the files.')
    group.add_argument(
        'filename',
        metavar='FILE',
        type=str,
        default='export.tar.gz',
        nargs='?',
        help='Path to the tarfile. Suffixes ".gz" and ".tgz" indicate '
        'gzip compression, whereas ".bz" and ".bz2" indicate bzip '
        'compression. Otherwise, no compression is used.')
    parser.add_argument('--input',
                        action="store_true",
                        dest="input",
                        help='Include input (INCAR/crystal.d12) files.')
    parser.add_argument('--dos',
                        action="store_true",
                        dest="dos",
                        help='Include Density of States (DOSCAR) files.')
    parser.add_argument('--structure',
                        action="store_true",
                        dest="structure",
                        help='Include structure input (POSCAR) files.')
    parser.add_argument('--charge',
                        action="store_true",
                        dest="charge",
                        help='Include charge (CHGCAR) files.')
    parser.add_argument('--contcar',
                        action="store_true",
                        dest="contcar",
                        help='Include CONTCAR files.')
    parser.add_argument(
        '--wavefunctions',
        action="store_true",
        dest="wavefunctions",
        help='Include wavefunctions (WAVECAR/crystal.98) files.')
    parser.add_argument('--procar',
                        action="store_true",
                        dest="procar",
                        help='Include PROCAR files.')
    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--down',
                       action="store_true",
                       dest="down",
                       help='Tar from one directory down.')
    group.add_argument('--from',
                       type=str,
                       dest="dir",
                       default=None,
                       help='Root directory from which to give filenames. '
                       'Defaults to current working directory.')
    group.add_argument(
        '--with',
        type=str,
        dest="others",
        nargs='*',
        help='Adds pattern or filename to files to export.'
        'Any file in any visited directory matching the given pattern '
        'will be added to the archive. This options can be given more than '
        'once if different file patterns are required.')

    try:
        args = parser.parse_args(event.split())
    except SystemExit as e:
        return None

    collect = shell.user_ns.get('collect', None)
    rootpath = getattr(collect, 'rootpath', None)
    if collect is None:
        print("Could not find 'collect' object in user namespace.")
        print("Please load a job-dictionary.")
        return

    kwargs = args.__dict__.copy()
    kwargs.pop('filename', None)

    if rootpath is None:
        if hasattr(shell.user_ns.get('collect', None), 'rootpath'):
            rootpath = shell.user_ns.get('collect').rootpath
    directory = getcwd() if rootpath is None else dirname(rootpath)

    if args.down:
        directory = join(directory, '..')
    elif args.dir is not None:
        directory = RelativePath(args.dir).path

    # set of directories visited.
    directories = set()
    # set of files to tar
    allfiles = set()
    for file in collect.files(**kwargs):
        allfiles.add(file)
        directories.add(dirname(file))
    # adds files from "with" argument.
    if hasattr(args.others, "__iter__"):
        for pattern in args.others:
            for dir in directories:
                for sfile in iglob(join(dir, pattern)):
                    if exists(sfile) and isfile(sfile):
                        allfiles.add(sfile)
    # adds current job folder.
    if interactive.jobfolder_path is not None:
        if isfile(interactive.jobfolder_path):
            allfiles.add(interactive.jobfolder_path)

    # now tar or list files.
    if args.aslist:
        from IPython.utils.text import SList
        directory = getcwd()
        return SList([relpath(file, directory) for file in allfiles])
    else:
        # get filename of tarfile.
        args.filename = relpath(RelativePath(args.filename).path, getcwd())
        if exists(args.filename):
            if not isfile(args.filename):
                print("{0} exists but is not a file. Aborting.".format(
                    args.filename))
                return
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input(
                    "File {0} already exists.\nOverwrite? [y/n] ".format(
                        args.filename))
            if a == 'n':
                print("Aborted.")
                return

        # figure out the type of the tarfile.
        if args.filename.find(extsep) == -1:
            endname = ''
        else:
            endname = args.filename[-args.filename[::-1].find(extsep) - 1:][1:]
        if endname in ['gz', 'tgz']:
            tarme = tarfile.open(args.filename, 'w:gz')
        elif endname in ['bz', 'bz2']:
            tarme = tarfile.open(args.filename, 'w:bz2')
        else:
            tarme = tarfile.open(args.filename, 'w')
        for file in allfiles:
            tarme.add(file, arcname=relpath(file, directory))
        tarme.close()
        print("Saved archive to {0}.".format(args.filename))
Beispiel #17
0
def launch(self, event, jobfolders):
    """ Launches each jobfolder in single pbs job """
    import six
    import subprocess
    from copy import deepcopy
    from os.path import dirname, join, basename, exists
    from os import remove
    from ... import pbs_string, default_pbs, qsub_exe, default_comm
    from .. import get_shell
    from . import get_walltime, get_queues, get_mppalloc
    from . import asone_script

    shell = get_shell(self)

    pbsargs = deepcopy(dict(default_comm))
    pbsargs.update(default_pbs)
    pbsargs['ppn'] = event.ppn
    if not get_walltime(shell, event, pbsargs):
        return
    if not get_queues(shell, event, pbsargs):
        return

    # gets python script to launch in pbs.
    pyscript = asone_script.__file__
    if pyscript[-1] == 'c':
        pyscript = pyscript[:-1]

    # creates file names.
    hasprefix = getattr(event, "prefix", None)

    def pbspaths(directory, jobname, suffix):
        """ creates filename paths. """
        name = '{0}-{1}{2}'.format(event.prefix, jobname, suffix) if hasprefix     \
               else '{0}{1}'.format(jobname, suffix)
        return join(directory, name)

    # now  loop over jobfolders
    pbsscripts = []
    for current, path in jobfolders:
        # Check number of jobs
        directory, nbjobs = dirname(path), 0
        for name, job in current.root.items():
            # avoid jobfolder which are off
            if job.is_tagged:
                continue
            # avoid successful jobs.unless specifically requested
            if hasattr(job.functional, 'Extract') and not event.force:
                p = join(directory, name)
                extract = job.functional.Extract(p)
                if extract.success:
                    print("Job {0} completed successfully. "                             \
                          "It will not be relaunched.".format(name))
                    continue
            nbjobs += 1
        if path.rfind('.') != -1:
            name = path[:path.rfind('.')]
        # now creates script
        pbsargs['n'] = get_mppalloc(shell, event, False)
        pbsargs['nnodes'] = (pbsargs['n'] + pbsargs['ppn'] - 1)                    \
            // pbsargs['ppn']
        pbsargs['err'] = pbspaths(directory, name, '.err')
        pbsargs['out'] = pbspaths(directory, name, '.out')
        pbsargs['name'] = basename(path)
        pbsargs['directory'] = directory
        pbsargs['scriptcommand']                                                   \
            = "{0} --nbprocs {n} --ppn {ppn} --pools={1} {2}"                     \
            .format(pyscript, event.pools, path, **pbsargs)
        pbsscripts.append(pbspaths(directory, name, '.script'))

        # write pbs scripts
        if exists(pbsscripts[-1]):
            a = ''
            while a not in ['n', 'y']:
                a = six.raw_input("PBS script {0} already exists.\n"
                                  "Are you sure this job is not currently running [y/n]? "
                                  .format(pbsscripts[-1]))
            if a == 'n':
                print("Aborting.")
                return
            remove(pbsscripts[-1])
        with open(pbsscripts[-1], "w") as file:
            string = pbs_string(**pbsargs) if hasattr(pbs_string, '__call__')        \
                else pbs_string.format(**pbsargs)
            file.write(string)
        assert exists(pbsscripts[-1])
        print("Created pbsscript {0} for job-folder {1}."                          \
              .format(pbsscripts[-1], path))

    if event.nolaunch:
        return
    # otherwise, launch.
    for script in pbsscripts:
        cmdLine = "{0} {1}".format(qsub_exe, script)
        subprocess.call(cmdLine, shell=True)