def species(self): """ :return: The list of species :rtype: list """ return [deep_unicode(x) for x in self._composition]
def symbols(self): ret = [] for specie in self: number_atoms_specie = self.composition[specie] for i in range(number_atoms_specie): ret.append(specie) return sorted(deep_unicode(ret))
def load(self): """ Loads an existing db from its configuration file """ rf = open(self.path + '/properties.json', 'r') self.properties = deep_unicode(_json.load(rf)) rf.close()
def generic_serializer(value): """ A generic serializer for very common values :param value: :return: """ value = deep_unicode(value) if value is None: return None elif isinstance(value, dict): new_value = {} for i in value: new_value[i] = generic_serializer(value[i]) return new_value elif hasattr(value, '__iter__'): return [generic_serializer(element) for element in value] elif isinstance(value, str): return value elif isinstance(value, Integral): return int(value) elif isinstance(value, Real): return float(value) elif isinstance(value, np.integer): return int(value) elif isinstance(value, np.float): return float(value) else: raise ValueError("Could not serialize this: %s of type: %s" % (value, type(value)))
def species(self): """ :return: The list of species :rtype: list """ return deep_unicode(sorted(list(self._composition.keys())))
def species(self): """List of species on the composition :return: The list of species, no particular order but atoms of the same specie are contiguous. :rtype: list >>> cp = Composition('H2O') >>> sorted(cp.species) ['H', 'O'] """ return [deep_unicode(x) for x in self._composition]
def load(self): """ Loads an existing db from its configuration file """ rf = open(self.path + '/db.json', 'r') try: jsonload = deep_unicode(_json.load(rf)) except ValueError: print("Error deserializing the object") jsonload = {'tags': {}} self.fromdict(jsonload) rf.close()
def load(self): assert isinstance(self.identifier, str) rf = open(self.path + '/metadata.json', 'r') self.metadatafromdict(deep_unicode(_json.load(rf))) rf.close() if self.tags is None: self.tags = [] if self.children is None: self.children = [] if self.parents is None: self.parents = [] self.structure = load_structure_json(self.path + '/structure.json') if os.path.isfile(self.path + '/properties.json'): rf = open(self.path + '/properties.json', 'r') try: self.properties = deep_unicode(_json.load(rf)) except ValueError: os.rename(self.path + '/properties.json', self.path + '/properties.json.FAILED') self.properties = None rf.close() self.load_originals()
def get_value(self, varname, return_iterable=False): if varname not in self.variables: raise ValueError( 'Input variables does not contain value for "%s"' % varname) value = self.variables[varname] value = deep_unicode(value) if return_iterable and isinstance(value, (int, float, str)): value = [value] return value
def __init__(self, name, tag, use_mongo=True): name = deep_unicode(name) self.tag = tag self.pcdb = None if isinstance(name, str): self.name = name if use_mongo: self.pcdb = PyChemiaDB(name) else: self.name = name.name if use_mongo: self.pcdb = name
def __init__(self, value=None): """ Creates a new composition, currently only absolute formulas are supported. :param value: (str, dict) The input argument could be a string with a chemical formula or the actual dictionary of species and values. The order of species is not guaranteed to be preserved. A iterable of atomic symbols is also accepted to build a composition object. :rtype: Composition >>> cp = Composition({'Ba': 2, 'Cu': 3, 'O': 7, 'Y': 1}) >>> cp.formula 'Ba2Cu3O7Y' >>> cp = Composition('Ba2Cu3O7Y') >>> cp2 = Composition(cp) >>> len(cp2) 4 >>> cp.nspecies 4 >>> cp = Composition(['O', 'H', 'O']) >>> len(cp) 2 >>> cp['O'] 2 """ # The internal dictionary where atom species and numbers of atoms of each specie are stored. self._composition = {} # Convert strings and dictionaries into unicode if value is not None: value = deep_unicode(value) # Case 1: The input is a formula if isinstance(value, str): self._set_composition(self.formula_parser(value)) # Case 2: The input is a dictionary elif isinstance(value, dict): self._set_composition(value) # Case 3: The input is another composition object elif isinstance(value, Composition): self._set_composition(value.composition) # Case 4: The input is an iterable of atomic symbols elif hasattr(value, "__len__"): dvalue = {} for i in value: if i in dvalue: dvalue[i] += 1 else: dvalue[i] = 1 self._set_composition(dvalue) else: self._composition = {}
def __init__(self, name, tag, use_mongo=True, direct_evaluation=False): name = deep_unicode(name) self.tag = tag self.pcdb = None self.direct_evaluation = direct_evaluation if isinstance(name, str): self.name = name if use_mongo: self.pcdb = PyChemiaDB(name) else: self.name = name.name if use_mongo: self.pcdb = name
def __init__(self, value=None): """ Creates a new composition, internally it is a dictionary where each specie is the key and the value is an integer with the number of atoms of that specie :param value: (str, dict) The value could be a string with a chemical formula or the actual dictionary of species and values :rtype: Composition Example: >>> import pychemia >>> comp = pychemia.Composition({'Ba': 2, 'Cu': 3, 'O': 7, 'Y': 1}) >>> comp.formula u'Ba2Cu3O7Y' >>> comp = pychemia.Composition('Ba2Cu3O7Y') >>> comp2 = pychemia.Composition(comp) >>> len(comp2) 4 >>> comp.nspecies 4 >>> comp = pychemia.Composition() >>> comp.composition {} >>> len(comp) 0 """ self._composition = {} if value is not None: value = deep_unicode(value) if isinstance(value, str): self._set_composition(self.formula_parser(value)) elif isinstance(value, dict): self._set_composition(value) elif isinstance(value, Composition): self._set_composition(value.composition) elif hasattr(value, "__len__"): dvalue = {} for i in value: if i in dvalue: dvalue[i] += 1 else: dvalue[i] = 1 self._set_composition(dvalue) else: self._composition = {}
def symbols(self): """List of species on the composition :return: A list of atomic symbols :rtype: list >>> cp = Composition('H2O') >>> cp.symbols ['H', 'H', 'O'] """ ret = [] for specie in self: number_atoms_specie = self.composition[specie] for i in range(number_atoms_specie): ret.append(specie) return sorted(deep_unicode(ret))
def from_dict(structdict): natom = structdict['natom'] symbols = deep_unicode(structdict['symbols']) periodicity = structdict['periodicity'] positions = np.array(structdict['positions']) if 'name' in structdict: name = structdict['name'] else: name = None if 'comment' in structdict: comment = structdict['comment'] else: comment = None if 'cell' in structdict: cell = np.array(structdict['cell']) else: cell = None if 'reduced' in structdict: reduced = np.array(structdict['reduced']) else: reduced = None if 'vector_info' in structdict: vector_info = structdict['vector_info'] else: vector_info = None if 'sites' in structdict: sites = structdict['sites'] else: sites = range(natom) if 'occupancies' in structdict: occupancies = structdict['occupancies'] else: occupancies = list(np.ones(natom)) return Structure(name=name, comment=comment, natom=natom, symbols=symbols, periodicity=periodicity, cell=cell, positions=positions, reduced=reduced, vector_info=vector_info, sites=sites, occupancies=occupancies)
def __init__(self, name, tag, use_mongo=True, direct_evaluation=False, distance_tolerance=0.1): name = deep_unicode(name) self.tag = tag self.pcdb = None self.direct_evaluation = direct_evaluation self.distance_tolerance = distance_tolerance if isinstance(name, str): self.name = name if use_mongo: self.pcdb = PyChemiaDB(name) else: self.name = name.name if use_mongo: self.pcdb = name
def sorted_formula(self, sortby='alpha', reduced=True): """ :return: The chemical formula. It could be sorted alphabetically using sortby='alpha', by electronegativity using sortby='electronegativity' or using Hill System with sortby='Hill' Just the first 3 letters are unambiguous and case is not taken in account so you can use 'alp', 'hil' or 'ele' :param sortby: (str) 'alpha' : Alphabetically 'electronegativity' : Electronegativity 'hill' : Hill System :param reduced: (bool) If the formula should be normalized :rtype: str .. notes: Hill exceptions have not being implemented yet >>> cp = Composition('YBa2Cu3O7') >>> cp.sorted_formula() 'Ba2Cu3O7Y' >>> cp.sorted_formula(sortby='hill') 'Ba2Cu3O7Y' >>> cp.sorted_formula(sortby='electroneg') 'Ba2YCu3O7' >>> cp = Composition('H10C5') >>> cp.sorted_formula(sortby='hill', reduced=True) 'CH2' >>> cp = Composition('IBr') >>> cp.sorted_formula(sortby='hill', reduced=False) 'BrI' >>> cp = Composition('Cl4C') >>> cp.sorted_formula(sortby='hill', reduced=False) 'CCl4' >>> cp = Composition('IH3C') >>> cp.sorted_formula(sortby='hill', reduced=False) 'CH3I' >>> cp = Composition('BrH5C2') >>> cp.sorted_formula(sortby='hill', reduced=False) 'C2H5Br' >>> cp = Composition('S04H2') >>> cp.sorted_formula(sortby='hill', reduced=False) 'H2S4' >>> cp = Composition('SO4H2') >>> cp.sorted_formula(sortby='hill', reduced=False) 'H2O4S' """ if reduced and self.gcd > 1: comp = Composition(self.composition) for i in comp.composition: comp._composition[i] //= self.gcd else: comp = self if sortby.lower()[:3] == 'ele': electroneg = list(electronegativity(comp.species)) # Not longer needed as electronegativy will return 0 for 'None' values # for i in range(len(electroneg)): # if electroneg[i] is None: # electroneg[i] = -1 sortedspecies = array(comp.species)[argsort(electroneg)] elif sortby.lower( )[:3] == "hil": # FIXME: Hill system exceptions not implemented sortedspecies = [] presortedspecies = sorted(comp.species) if 'C' in presortedspecies: sortedspecies.append('C') presortedspecies.pop(presortedspecies.index('C')) if 'H' in presortedspecies: sortedspecies.append('H') presortedspecies.pop(presortedspecies.index('H')) sortedspecies += presortedspecies else: sortedspecies = sorted(comp.species) ret = u'' for specie in sortedspecies: ret += '%s' % specie if comp.composition[specie] > 1: ret += "%d" % comp.composition[specie] return deep_unicode(ret)
def load_json(filename): filep = open(filename, 'r') structdict = deep_unicode(json.load(filep)) filep.close() return Structure.from_dict(structdict)
def write_key(self, varname): """ Receives an input variable and write their contents properly according with their kind and length Args: varname: The name of the input variable """ ret = (varname.ljust(15)) + " = " if varname not in self.__dict__: raise ValueError("[ERROR] input variable: '%s' is not declared" % varname) value = self.__dict__[varname] value = deep_unicode(value) if isinstance(value, bool): if value: ret += '.TRUE.' else: ret += '.FALSE.' elif isinstance(value, Number): ret += str(value) elif isinstance(value, str): ret += value else: # Assume that the variables are integer and test if such assumption # is true integer = True real = False string = False compact = True # Get the general kind of values for the input variable for j in self.__dict__[varname]: try: if not float(j).is_integer(): # This is the case of non integer values integer = False real = True string = False if len(str(float(j))) > 7: compact = False except ValueError: # This is the case of '*1' that could not # be converted because we do not know the size # of the array integer = False real = False string = True if len(self.__dict__[varname]) > 1: print(varname) tmp = [(self.__dict__[varname][0], 1)] prev = self.__dict__[varname][0] for i in self.__dict__[varname][1:]: if i == prev: tmp[-1] = (i, tmp[-1][1] + 1) else: tmp.append((i, 1)) prev = i counter = 0 for j in tmp: if j[1] > 3: if real: if compact: ret += (" %d*%g" % (j[1] - j[1] % 3, j[0])).rjust(8) else: ret += " %d*%g" % (j[1] - j[1] % 3, j[0]) elif integer: ret += " %d*%d" % (j[1] - j[1] % 3, j[0]) else: ret += " %d*%s" % (j[1] - j[1] % 3, j[0]) if j[1] % 3 != 0: for i in range(j[1] % 3): if real: if compact: ret += (" %g" % j[0]).rjust(8) else: ret += " %17.10e" % j[0] elif integer: ret += " %d" % j[0] else: ret += " %s" % j[0] counter += j[1] else: for i in range(j[1]): if real: if compact: ret += (" %g" % j[0]).rjust(8) else: ret += " %17.10e" % j[0] elif integer: ret += " %d" % j[0] elif string: ret += " %s" % j[0] counter += 1 ret += ";\n" return ret
def symbol(self, symprec=1e-5): return deep_unicode(self.get_symmetry_dataset(symprec)['international'])
def sorted_formula(self, sortby='alpha', reduced=True): """ :return: The chemical formula. It could be sorted alphabetically using sortby='alpha', by electronegativity using sortby='electroneg' or using Hill System with sortby='Hill' :param sortby: (str) 'alpha' : Alphabetically 'electroneg' : Electronegativity 'hill' : Hill System :param reduced: (bool) If the formula should be normalized :rtype: str >>> comp=Composition('YBa2Cu3O7') >>> comp.sorted_formula() u'Ba2Cu3O7Y' >>> comp.sorted_formula(sortby='hill') u'Ba2Cu3O7Y' >>> comp.sorted_formula(sortby='electroneg') u'Ba2YCu3O7' >>> comp = Composition('H10C5') >>> comp.sorted_formula(sortby='hill', reduced=True) u'CH2' >>> comp = Composition('IBr') >>> comp.sorted_formula(sortby='hill', reduced=False) u'BrI' >>> comp = Composition('Cl4C') >>> comp.sorted_formula(sortby='hill', reduced=False) u'CCl4' >>> comp = Composition('IH3C') >>> comp.sorted_formula(sortby='hill', reduced=False) u'CH3I' >>> comp = Composition('BrH5C2') >>> comp.sorted_formula(sortby='hill', reduced=False) u'C2H5Br' >>> comp = Composition('S04H2') >>> comp.sorted_formula(sortby='hill', reduced=False) u'H2S4' >>> comp = Composition('SO4H2') >>> comp.sorted_formula(sortby='hill', reduced=False) u'H2O4S' """ if reduced and self.gcd > 1: comp = Composition(self.composition) for i in comp.composition: comp._composition[i] //= self.gcd else: comp = self if sortby == 'electroneg': electroneg = list(electronegativity(comp.species)) for i in range(len(electroneg)): if electroneg[i] is None: electroneg[i] = -1 sortedspecies = array(comp.species)[argsort(electroneg)] elif sortby == "hill": # FIXME: Hill system exceptions not implemented sortedspecies = [] presortedspecies = sorted(comp.species) if 'C' in presortedspecies: sortedspecies.append('C') presortedspecies.pop(presortedspecies.index('C')) if 'H' in presortedspecies: sortedspecies.append('H') presortedspecies.pop(presortedspecies.index('H')) sortedspecies += presortedspecies else: sortedspecies = sorted(comp.species) ret = u'' for specie in sortedspecies: ret += '%s' % specie if comp.composition[specie] > 1: ret += "%d" % comp.composition[specie] return deep_unicode(ret)
def load_json(self, filename): filep = open(filename, 'r') vj_dict = deep_unicode(json.load(filep)) self.fromdict(vj_dict)