diff --git a/README.rst b/README.rst index 2b00ea3c..37b140ad 100644 --- a/README.rst +++ b/README.rst @@ -58,16 +58,30 @@ Otherwise, these packages should be available on `PyPI ` 6. netCDF4 +7. pyyaml 3.1.0+ + Optional dependencies --------------------- Optional libraries that are required if you need certain features: -1. nose - For complete unittesting. +1. wxPython - For the GUI -2. wxPython - For the GUI +2. wxmplot + +3. nose - For complete unittesting. + +Installing wxPython +------------------- + +Mac users can download the + +Linux users: + TODO + +The directory `abipy.gui.demos` contains demos that can be used to test the installation +(run the script `runall.py` to have an overview of the different graphical interfaces). -3. wxmplot Using abipy =========== diff --git a/abipy/__init__.py b/abipy/__init__.py index 356962bb..f69b1e64 100644 --- a/abipy/__init__.py +++ b/abipy/__init__.py @@ -72,7 +72,7 @@ def abifile_subclass_from_filename(filename): def abiopen(filepath): """ - Factory function that returns the appropriate object + Factory function that opens any file supported by abipy. Args: filepath: diff --git a/abipy/abilab.py b/abipy/abilab.py index 2329893b..d4919102 100644 --- a/abipy/abilab.py +++ b/abipy/abilab.py @@ -3,6 +3,7 @@ from pymatgen.io.abinitio.task import TaskManager from pymatgen.io.abinitio import qadapters as qadapters import abipy.core.constants as constants +from abipy import abiopen from abipy.core.structure import Structure, StructureModifier from abipy.htc.input import AbiInput from abipy.htc.workflows import Workflow diff --git a/abipy/core/structure.py b/abipy/core/structure.py index 955e0971..1d567389 100644 --- a/abipy/core/structure.py +++ b/abipy/core/structure.py @@ -1,4 +1,4 @@ -"""This module defines the structure object that store information on the crystalline structure and its symmetries.""" +"""This module defines basic objects representing the crystalline structure.""" from __future__ import division, print_function import collections @@ -10,7 +10,6 @@ from .symmetries import SpaceGroup from abipy.iotools import as_etsfreader, Visualizer from abipy.iotools import xsf - __all__ = [ "Lattice", "Structure", @@ -19,15 +18,14 @@ __all__ = [ class Lattice(pymatgen.Lattice): """ - Extends the pymatgen Lattice with methods that allows one to construct - the object from ABINIT variables or to produce the set of input variables - from a structure + Extends pymatgen.Lattice with methods that allows one + to construct a Lattice object from ABINIT variables. """ @classmethod def from_abivars(cls, d): """ - Returns a new instance from a dictionary with the ABINIT variable that - define the unit cell. + Returns a new instance from a dictionary with the variables + used in ABINIT to define the unit cell. """ rprim = d.get("rprim", None) angdeg = d.get("angdeg", None) @@ -61,12 +59,12 @@ class Structure(pymatgen.Structure): @classmethod def from_file(cls, filepath): """ - Return a new instance from a NetCDF file containing - crystallographic data in the ETSF-IO format. + Return a new Structure instance from a NetCDF file Args: - ncdata: - filename or NetcdfReader instance. + filename: + netcdf file with crystallographic data in the ETSF-IO format. + or any other file format supported by `pymatgen.io.smartio`. """ if filepath.endswith(".nc"): file, closeit = as_etsfreader(filepath) @@ -102,7 +100,7 @@ class Structure(pymatgen.Structure): @property def has_spacegroup(self): - """True is self contains info on the spacegroup.""" + """True is the structure contains info on the spacegroup.""" return self.spacegroup is not None @property @@ -161,7 +159,7 @@ class Structure(pymatgen.Structure): @property def hsym_stars(self): """ - List of `Star` objects. Each start is associated to one of the special k-points + List of `Star` objects. Each star is associated to one of the special k-points present in the pymatgen database. """ try: @@ -274,6 +272,7 @@ class Structure(pymatgen.Structure): @classmethod def from_abivars(cls, d): + """Build a `Structure` object from a dictionary containing ABINIT variables.""" lattice = Lattice.from_abivars(d) coords, coords_are_cartesian = d.get("xred", None), False @@ -309,8 +308,13 @@ class Structure(pymatgen.Structure): def write_structure(self, filename): """See `pymatgen.io.smartio.write_structure`""" - from pymatgen.io.smartio import write_structure - write_structure(self, filename) + + if filepath.endswith(".nc"): + raise NotImplementedError("Cannot write a structure to a netcdfile file yet") + + else: + from pymatgen.io.smartio import write_structure + write_structure(self, filename) def displace(self, displ, eta, frac_coords=True): """ diff --git a/abipy/data/runs/README.rst b/abipy/data/runs/README.rst index 680353c7..b74ce732 100644 --- a/abipy/data/runs/README.rst +++ b/abipy/data/runs/README.rst @@ -12,5 +12,20 @@ advantages: In order to facilitate the automatic execution and validation, the python scripts must satisfy some basic rules and conventions. -1) The name of the script must match the regular expression: - run_[*].py +#. The name of the script must match the regular expression run_[*].py so that + we can run all the tests easily with run_all.py + +#. The execution of the test should be managed by a `Tester` object + The `Tester` is responsible for the definition of the working directory (constructed + from the name of the script by just removing the prefix `run_`), the submission + of the calculation (tester.set_work_and_run) and the analysis of the final results + (tester.finalize). + +#. The script should remove all the output files produced by the run that are not needed + for the automatic tests and/or the tutorials. Each file should have a unique (meanigfull) name + so that we can easily access it with the syntax: + + import abipy.data as data + path_to_reference_file = data.ref_file("basename_of_the_file") + + An exception is raised if this rule is not respected. diff --git a/abipy/data/runs/run_raman.py b/abipy/data/runs/run_raman.py index d8db2f71..3540a319 100755 --- a/abipy/data/runs/run_raman.py +++ b/abipy/data/runs/run_raman.py @@ -106,6 +106,8 @@ def raman_workflow(workdir, structure, pseudos, shiftk): ) # Initialize the workflow. + policy=dict(autoparal=1, max_ncpus=2) + manager = abilab.TaskManager(qtype="slurm", qparams=dict( ntasks=2, @@ -123,10 +125,10 @@ def raman_workflow(workdir, structure, pseudos, shiftk): LD_LIBRARY_PATH="/home/naps/ygillet/NAPS/intel13/lib:$LD_LIBRARY_PATH", ), mpi_runner="mpirun", - policy=dict(autoparal=1, max_ncpus=2), + policy=policy ) - #manager = abilab.TaskManager.simple_mpi(mpi_ncpus=1) + manager = abilab.TaskManager.simple_mpi(mpi_ncpus=1, policy=policy) work = abilab.Workflow(workdir, manager) diff --git a/abipy/electrons/ebands.py b/abipy/electrons/ebands.py index d72012aa..7a80d458 100644 --- a/abipy/electrons/ebands.py +++ b/abipy/electrons/ebands.py @@ -62,6 +62,7 @@ class KSState(collections.namedtuple("KSState", "spin kpoint band eig occ")): return tuple(fields) def asdict(self): + """Convert self into a dict.""" return super(KSState, self)._asdict() def to_strdict(self, fmt=None): @@ -242,10 +243,13 @@ class ElectronBands(object): assert new.__class__ == cls return new - def __str__(self): - return self.tostring() + def __repr__(self): + return self.to_string() - def tostring(self, prtvol=0): + def __str__(self): + return self.to_string() + + def to_string(self, prtvol=0): """String representation.""" lines = [] app = lines.append @@ -419,7 +423,6 @@ class ElectronBands(object): def enemin(self, spin=None, band=None): """Compute the minimum of the eigenvalues.""" - spin_range = self.spins if spin is not None: assert isinstance(spin, int) @@ -1231,35 +1234,6 @@ class ElectronBands(object): return 1.0/ders2 -#class NestingFactor(object): -# -# def __init__(self, bands): -# -# self.bands = bands -# -# # Check whether k-points form a homogeneous sampling. -# if not self.bands.has_bzmesh: -# msg = "The computation of the nesting factor requires a homogeneous k-point sampling" -# raise ValueError(msg) -# -# @classmethod -# def from_file(cls, filepath): -# """ -# Initialize the object from a netcdf file containing an electronic band structure. -# """ -# return cls(ElectronBands.from_file(filepath)) -# -# def compute_nesting(self, qpath): -# mesh, values = None, None -# return Function1D(mesh, values) -# -# def plot(self, qpath): -# nesting = self.compute_nesting(qpath) -# nesting.plot() - -######################################################################################### - - class ElectronBandsPlotter(object): """ Class for plotting electronic bands structure and DOSes. @@ -1592,3 +1566,32 @@ class ElectronsReader(ETSF_Reader, KpointsReaderMixin): #def read_xc_parameters(self): # """Returns a dictionary with info on the XC functional.""" # return XC_Parameters.from_ixc(self.read_value("ixc")) + + +#class NestingFactor(object): +# +# def __init__(self, bands): +# +# self.bands = bands +# +# # Check whether k-points form a homogeneous sampling. +# if not self.bands.has_bzmesh: +# msg = "The computation of the nesting factor requires a homogeneous k-point sampling" +# raise ValueError(msg) +# +# @classmethod +# def from_file(cls, filepath): +# """ +# Initialize the object from a netcdf file containing an electronic band structure. +# """ +# return cls(ElectronBands.from_file(filepath)) +# +# def compute_nesting(self, qpath): +# mesh, values = None, None +# return Function1D(mesh, values) +# +# def plot(self, qpath): +# nesting = self.compute_nesting(qpath) +# nesting.plot() + +######################################################################################### diff --git a/abipy/scripts/abilab b/abipy/scripts/abilab new file mode 100755 index 00000000..a84bcf1d --- /dev/null +++ b/abipy/scripts/abilab @@ -0,0 +1,55 @@ +#!/usr/bin/env python +from IPython.config.loader import Config + +try: + get_ipython + +except NameError: + nested = 0 + cfg = Config() + prompt_config = cfg.PromptManager + prompt_config.in_template = 'In [\\#]: ' + prompt_config.in2_template = ' .\\D.: ' + prompt_config.out_template = 'Out[\\#]: ' + +else: + print("Running nested copies of IPython.") + print("The prompts for the nested copy have been modified") + cfg = Config() + nested = 1 + +# First import the embeddable shell class +from IPython.frontend.terminal.embed import InteractiveShellEmbed + +# Now create an instance of the embeddable shell. The first argument is a +# string with options exactly as you would type them if you were starting +# IPython at the system command line. Any parameters you want to define for +# configuration can thus be specified here. +import pymatgen as pymatgen +import abipy.abilab as abilab + +#from pymatgen import * +from abipy.abilab import * + +abi_builtins = [n for n in dir(abilab) if not n.startswith("_")] + #[n for n in dir(pymatgen) if not n.startswith("_")] + \ +del abilab #, pymatgen + +abi_builtins = sorted(set(abi_builtins)) + +import textwrap +banner = textwrap.fill(str(abi_builtins), width=70) +del textwrap + +banner = ("Custom ipython environment for abipy. Useful aliases such as:\n" + + banner + "\n" + + "have been loaded.\n" + + "Type abi_builtins to get the complete list." + ) + +ipshell = InteractiveShellEmbed( + config=cfg, + banner1=banner, + exit_msg='Leaving abipy interpreter, back to program.') + +ipshell()