Example #1
0
    def __init__(self, potential):
        """
        Builds a PotInfo component class.

        Parameters
        ----------
        potential : Potential, str or DataModelDict
            A Potential record object or DataModelDict contents for a Potential
            record.  This prodives the information to link the Potential to the
            Action.
        """
        if isinstance(potential, Potential.Potential):

            # Extract relevant properties from the Potential object
            self.__id = potential.id
            self.__key = potential.key
            self.__dois = []
            for citation in potential.citations:
                try:
                    self.__dois.append(citation.doi)
                except:
                    pass
            self.__fictional = potential.fictional
            self.__elements = potential.elements
            self.__othername = potential.othername

        else:

            # Extract relevant properties from potential record contents
            model = DM(potential).find('potential')
            self.__id = model['id']
            self.__key = model['key']
            self.__dois = model.aslist('doi')

            felements = model.aslist('fictional-element')
            oelements = model.aslist('other-element')
            elements = model.aslist('element')

            if len(felements) > 0:
                assert len(elements) == 0
                self.__fictional = True
                self.__elements = felements
            else:
                assert len(elements) > 0
                self.__fictional = False
                self.__elements = elements
            if len(oelements) > 0:
                assert len(oelements) == 1
                self.__othername = oelements[0]
            else:
                self.__othername = None
Example #2
0
 def load(self, model):
     model = DM(model).find('request')
     self.date = model['date']
     self.comment = model.get('comment', None)
     self.__systems = []
     for system in model.aslist('system'):
         self.add_system(model=DM([('system', system)]))
Example #3
0
    def load_model(self, model, name=None):
        """
        Loads record contents from a given model.

        Parameters
        ----------
        model : str or DataModelDict
            The model contents of the record to load.
        name : str, optional
            The name to assign to the record.  Often inferred from other
            attributes if not given.
        """
        super().load_model(model, name=name)
        req = DM(model).find('request')
        self.date = req['date']
        self.comment = req.get('comment', None)
        self.__systems = []
        for system in req.aslist('system'):
            self.add_system(model=DM([('system',system)]))

        if name is not None:
            self.name = name
        else:
            elements = []
            for system in self.systems:
                elements.extend(system.elements)
            self.name = f'{self.date} {" ".join(elements)}'
Example #4
0
 def load(self, model):
     model = DM(model).find('action')
     self.date = model['date']
     self.type = model['type']
     self.comment = model.get('comment', None)
     self.__potentials = []
     for potential in model.aslist('potential'):
         self.potentials.append(PotInfo(DM([('potential', potential)])))
Example #5
0
    def __init__(self, potential):

        if isinstance(potential, Potential):
            self.__id = potential.id
            self.__key = potential.key
            self.__dois = []
            for citation in potential.citations:
                self.__dois.append(citation.doi)
            self.__fictional = potential.fictional
            self.__elements = potential.elements
            self.__othername = potential.othername

        elif isinstance(potential, DM):
            model = DM(potential).find('potential')
            self.__id = model['id']
            self.__key = model['key']
            self.__dois = model.aslist('doi')

            felements = model.aslist('fictional-element')
            oelements = model.aslist('other-element')
            elements = model.aslist('element')

            if len(felements) > 0:
                assert len(elements) == 0
                self.__fictional = True
                self.__elements = felements
            else:
                assert len(elements) > 0
                self.__fictional = False
                self.__elements = elements
            if len(oelements) > 0:
                assert len(oelements) == 1
                self.__othername = oelements[0]
            else:
                self.__othername = None

        else:
            raise TypeError('Invalid potential content')
Example #6
0
    def __init__(self,
                 natoms=None,
                 atype=None,
                 pos=None,
                 prop=None,
                 model=None,
                 safecopy=False,
                 **kwargs):
        """
        Class initializer.
        
        Parameters
        ==========
        natoms : int, optional
            The number of atoms.  If not given, will be inferred from other
            parameters if possible, or set to 1 if not possible.
        atype : int or list/ndarray of int, optional
            The integer atomic types to assign to all atoms.  Default is to
            set all atypes to 1.
        pos : list/ndarray of float, optional
            The atomic positions to assign to all atoms.  Default is to set
            each atom's position to [0,0,0].
        model : str or DataModelDict, optional
            File path or content of a JSON/XML data model containing all
            atom information.  Cannot be given with any other parameters.
        prop : dict, optional
            Dictionary containing all per-atom properties.  Can be used
            instead of atype, pos, and kwargs.  This is for backwards
            compatibility support with atomman version 1.
        safecopy : bool, optional
            Flag indicating if values are to be copied before setting.  For
            property values given as numpy arrays, direct setting (False,
            default) may result in the Atoms' property pointing to the original
            numpy array.  Using safecopy=True deep copies the property values
            before setting to avoid this.  Note that safecopy=True may be
            considerably slower for large numbers of atoms and/or properties.
        kwargs : any
            All additional key/value pairs are assigned as properties.
        
        Returns
        =======
        Atoms
            The Atoms object.
        """

        # Check for model
        if model is not None:
            try:
                assert natoms is None
                assert atype is None
                assert pos is None
                assert prop is None
                assert len(kwargs) == 0
            except:
                raise ValueError(
                    'model cannot be given with any other parameters')

            # Extract natoms and properties from data model
            model = DM(model).find('atoms')
            natoms = model['natoms']
            prop = OrderedDict()
            for propmodel in model.aslist('property'):
                prop[propmodel['name']] = uc.value_unit(propmodel['data'])

        # Check for prop dictionary
        if prop is not None:
            if atype is not None and pos is not None and len(kwargs) > 0:
                raise ValueError(
                    'prop dict cannot be given with keyword properties')

            # Divide prop into keyword arguments
            atype = prop.pop('atype', None)
            pos = prop.pop('pos', None)
            kwargs = prop

        # Check atype parameter values
        if atype is not None:
            atype = np.asarray(atype, dtype='uint64')

            # Handle single atype
            if atype.ndim == 0:
                natoms_atype = 1

            # Handle list of atype
            elif atype.ndim == 1:
                natoms_atype = atype.shape[0]
            else:
                raise ValueError('Only one atype per atom allowed')
        else:
            atype = np.array([1], dtype='uint64')
            natoms_atype = 1

        # Check pos parameter values
        if pos is not None:
            pos = np.asarray(pos, dtype='float64')

            # Handle single pos
            if pos.ndim == 1:
                if pos.shape[0] == 3:
                    natoms_pos = 1
                else:
                    raise ValueError('pos per atom must be 3-dimensional')

            # Handle list of pos
            elif pos.ndim == 2:
                if pos.shape[1] == 3:
                    natoms_pos = pos.shape[0]
                else:
                    raise ValueError('pos per atom must be 3-dimensional')
            else:
                raise ValueError('too many dimensions for pos')
        else:
            pos = np.zeros((1, 3), dtype='float64')
            natoms_pos = 1

        # Check natoms parameter values
        if natoms is not None:
            natoms = int(natoms)
            if ((natoms_atype == 1 or natoms_atype == natoms)
                    and (natoms_pos == 1 or natoms_pos == natoms)):
                pass
            else:
                raise ValueError(
                    'natoms and length of atype/pos not compatible')
        else:
            if natoms_atype == natoms_pos:
                natoms = natoms_atype
            elif natoms_atype == 1:
                natoms = natoms_pos
            elif natoms_pos == 1:
                natoms = natoms_atype
            else:
                raise ValueError('lengths of atype and pos not compatible')

        # Initialize underlying private class attributes
        super(Atoms, self).__setattr__('_Atoms__natoms', natoms)
        super(Atoms, self).__setattr__('_Atoms__view',
                                       Atoms.PropertyDict(self))
        super(Atoms, self).__setattr__('_Atoms__dir', deepcopy(dir(self)))

        # Set properties
        if safecopy:
            self.view['atype'] = deepcopy(atype)
            self.view['pos'] = deepcopy(pos)
            for key, value in kwargs.items():
                self.view[key] = deepcopy(value)
        else:
            self.view['atype'] = atype
            self.view['pos'] = pos
            for key, value in kwargs.items():
                self.view[key] = value
def structure_static(xml_lib_dir):
    calc_name = 'structure_static'
    groups = os.path.join(xml_lib_dir, '*', calc_name, '*')
    
    error_dict = DataModelDict()
    
    for group_dir in glob.iglob(groups):
        if os.path.isdir(group_dir):
            calc_dir, group_name = os.path.split(group_dir)
            pot_name = os.path.basename(os.path.dirname(calc_dir))
            print pot_name
            try:
                with open(os.path.join(calc_dir, 'badlist.txt'), 'r') as f:
                    badlist = f.read().split()
            except:
                badlist = []
            
            data = DataModelDict()
            
            for sim_path in glob.iglob(os.path.join(group_dir, '*.xml')):
                sim_file = os.path.basename(sim_path)
                sim_name = sim_file[:-4]
                
                if sim_name in badlist:
                    continue
                    
                with open(sim_path) as f:
                    sim = DataModelDict(f)['calculation-crystal-phase']
                
                if 'error' in sim:
                    badlist.append(sim_name)
                    error_message = sim['error']
                    error = 'Unknown error'
                    for line in error_message.split('\n'):
                        if 'Error' in line:
                            error = line
                    error_dict.append(error, sim_name)
                    continue
            
                try:
                    cell = sim['relaxed-atomic-system']['cell']
                except:
                    tar_gz_path = sim_path[:-4] + '.tar.gz'
                    if os.isfile(tar_gz_path):
                        error_dict.append('Unknown error', sim_name)
                    continue
                    
                data.append('key', sim.get('calculation-id', ''))
                data.append('file', sim['crystal-info'].get('artifact', ''))
                data.append('symbols', '_'.join(sim['crystal-info'].aslist('symbols')))
                
                data.append('Temperature (K)', sim['phase-state']['temperature']['value'])
                data.append('Pressure (GPa)', sim['phase-state']['pressure']['value'])

                cell = cell[cell.keys()[0]]
                data.append('Ecoh (eV)', sim['cohesive-energy']['value'] )
                if 'a' in cell:
                    data.append('a (A)', cell['a']['value'])
                else:
                    data.append('a (A)', '')
                if 'b' in cell:
                    data.append('b (A)', cell['b']['value'])
                else:
                    data.append('b (A)', '')
                if 'c' in cell:
                    data.append('c (A)', cell['c']['value'])
                else:
                    data.append('c (A)', '')
                C_dict = {}
                for C in sim['elastic-constants'].iteraslist('C'):
                    C_dict[C['ij']] = C['stiffness']['value']
                data.append('C11 (GPa)', C_dict.get('1 1', ''))
                data.append('C22 (GPa)', C_dict.get('2 2', ''))
                data.append('C33 (GPa)', C_dict.get('3 3', ''))
                data.append('C12 (GPa)', C_dict.get('1 2', ''))
                data.append('C13 (GPa)', C_dict.get('1 3', ''))
                data.append('C23 (GPa)', C_dict.get('2 3', ''))
                data.append('C44 (GPa)', C_dict.get('4 4', ''))
                data.append('C55 (GPa)', C_dict.get('5 5', ''))
                data.append('C66 (GPa)', C_dict.get('6 6', ''))
                
            
            if len(data.keys()) > 0: 
                with open(os.path.join(calc_dir, 'structure_static_'+group_name+'.csv'), 'w') as f:
                    f.write(','.join(data.keys())+'\n')
                    for i in xrange(len(data.aslist('key'))):
                        f.write(','.join([str(data.aslist(k)[i]) for k in data.keys()]) + '\n')

            
            with open(os.path.join(calc_dir, 'badlist.txt'), 'w') as f:
                for bad in badlist:
                    f.write(bad+'\n')
Example #8
0
    def __init__(self,
                 atoms=None,
                 box=None,
                 pbc=None,
                 scale=False,
                 symbols=None,
                 masses=None,
                 model=None,
                 safecopy=False):
        """
        Initialize a System by joining an am.Atoms and am.Box instance.
        
        Parameters
        ----------
        atoms : atomman.Atoms, optional
            The underlying Atoms object to build system around.
        box : atomman.Box, optional
            The underlying box object to build system around.
        pbc : tuple or list of bool, optional
            Indicates which of the dimensions related to the three box vectors
            are periodic.  Default value is (True, True, True).
        scale : bool, optional
            If True, atoms.pos will be scaled relative to the box.  Default
            value is False.
        symbols : tuple, optional
            A list of the element symbols for each atom atype.  If len(symbols)
            is less than natypes, then missing values will be set to None.
            Default sets list with all None values.
        masses : tuple, optional
            A list of the masses for each atom atype.  If len(symbols) is less
            than natypes, then missing values will be set to None.  Default
            sets list with all None values.
        model : str or DataModelDict, optional
            File path or content of a JSON/XML data model containing all
            system information.  Cannot be given with atoms, box or scale.
        safecopy : bool, optional
            Flag indicating if values are to be copied before setting.  For
            values given as objects, direct setting (False, default) may result
            in the System pointing to the original object.  Using safecopy=True
            deep copies the objects before setting to avoid this.  Note that
            safecopy=True may be considerably slower for large numbers of atoms
            and/or properties.
        
        Returns
        =======
        System
            The System object.
        """
        # Check for model
        if model is not None:
            try:
                assert atoms is None
                assert box is None
                assert scale is False
            except:
                raise ValueError(
                    'model cannot be given with atoms, box or scale parameters'
                )

            # Load data model
            model = DM(model).find('atomic-system')

            # Extract values from model
            box = Box(model=model)
            atoms = Atoms(model=model)
            if pbc is None:
                pbc = model['periodic-boundary-condition']
            if symbols is None:
                symbols = tuple(model.aslist('atom-type-symbol'))
            if masses is None:
                masses = tuple(model.aslist('atom-type-mass'))

        # Interpret given/missing parameters
        else:
            # Set default atoms or deepcopy
            if atoms is None:
                atoms = Atoms()
            elif safecopy:
                atoms = deepcopy(atoms)

            # Set default box or deepcopy
            if box is None:
                box = Box()
            elif safecopy:
                box = deepcopy(box)

            # Set default pbc
            if pbc is None:
                pbc = (True, True, True)

            # Set default masses
            if masses is None:
                masses = []
            else:
                masses = aslist(masses)

            # Set default symbols
            if symbols is None:
                symbols = [None for i in range(len(masses))]
            else:
                symbols = aslist(symbols)

            # Check data types
            if not isinstance(atoms, Atoms):
                raise TypeError('Invalid atoms type')
            if not isinstance(box, Box):
                raise TypeError('Invalid box type')
            if not isinstance(scale, bool):
                raise TypeError('Invalid scale type')

        # Set properties
        self.__atoms = atoms
        self.__box = box
        self.pbc = pbc
        self.__transformation = np.identity(3)

        self.symbols = symbols
        self.masses = masses

        # Scale pos if needed
        if scale is True:
            self.atoms_prop('pos', value=self.atoms.pos, scale=True)

        # Scale model properties if needed
        if model is not None:
            for prop in model['atoms'].aslist('property'):
                if prop['data'].get('unit', None) == 'scaled':
                    self.atoms.view[prop['name']] = self.unscale(
                        self.atoms.view[prop['name']])

        # Set atoms indexer
        self.__atoms_ix = System._AtomsIndexer(self)
Example #9
0
    def __init__(self, atoms=None, box=None, pbc=None,
                 scale=False, symbols=None, model=None):
        """
        Initialize a System by joining an am.Atoms and am.Box instance.
        
        Parameters
        ----------
        atoms : atomman.Atoms, optional
            The underlying Atoms object to build system around.
        box : atomman.Box, optional
            The underlying box object to build system around.
        pbc : tuple or list of bool, optional
            Indicates which of the dimensions related to the three box vectors
            are periodic.  Default value is (True, True, True).
        scale : bool, optional
            If True, atoms.pos will be scaled relative to the box.  Default
            value is False.
        symbols : tuple, optional
            A list of the element symbols for each atom atype.  If len(symbols)
            is less than natypes, then missing values will be set to None.
            Default value is (,), i.e. all values set to None.
        model : str or DataModelDict, optional
            File path or content of a JSON/XML data model containing all
            system information.  Cannot be given with atoms, box or scale.
        """
        # Check for model
        if model is not None:
            try:
                assert atoms is None
                assert box is None
                assert scale is False
            except:
                raise ValueError('model cannot be given with atoms, box or scale parameters')
            
            # Load data model
            model = DM(model).find('atomic-system')

            # Extract values from model
            box = Box(model=model)
            atoms = Atoms(model=model)
            if pbc is None:
                pbc = model['periodic-boundary-condition']
            if symbols is None:
                symbols = tuple(model.aslist('atom-type-symbol'))

        else:
            # Set default values
            if atoms is None:
                atoms = Atoms()
            if box is None:
                box = Box()
            if pbc is None:
                pbc= (True, True, True)
            if symbols is None:
                symbols=()

            # Check data types
            if not isinstance(atoms, Atoms):
                raise TypeError('Invalid atoms type')
            if not isinstance(box, Box):
                raise TypeError('Invalid box type')
            if not isinstance(scale, bool):
                raise TypeError('Invalid scale type')
        
        # Set properties
        self.__atoms = atoms
        self.__box = box
        self.pbc = pbc
        self.__transformation = np.identity(3)
        
        if isinstance(symbols, stringtype):
            symbols = (symbols,)
        assert len(symbols) <= self.natypes
        self.__symbols = tuple(symbols)
        
        # Scale pos if needed
        if scale is True:
            self.atoms_prop('pos', value=atoms.pos, scale=True)

        # Scale model properties if needed
        if model is not None:
            for prop in model['atoms'].aslist('property'):
                if prop['data'].get('unit', None) == 'scaled':
                    self.atoms.view[prop['name']] = self.unscale(self.atoms.view[prop['name']]) 

        # Set atoms indexer
        self.__atoms_ix = System._AtomsIndexer(self)