def __init__(self, row, meta={}, subscript=None, prefix=''): self.row = row self.cell = [['{:.3f}'.format(a) for a in axis] for axis in row.cell] par = ['{:.3f}'.format(x) for x in cell_to_cellpar(row.cell)] self.lengths = par[:3] self.angles = par[3:] self.stress = row.get('stress') if self.stress is not None: self.stress = ', '.join('{0:.3f}'.format(s) for s in self.stress) self.formula = formula_metal(row.numbers) if subscript: self.formula = subscript.sub(r'<sub>\1</sub>', self.formula) kd = meta.get('key_descriptions', {}) create_layout = meta.get('layout') or default_layout self.layout = create_layout(row, kd, prefix) self.dipole = row.get('dipole') if self.dipole is not None: self.dipole = ', '.join('{0:.3f}'.format(d) for d in self.dipole) self.data = row.get('data') if self.data: self.data = ', '.join(self.data.keys()) self.constraints = row.get('constraints') if self.constraints: self.constraints = ', '.join(c.__class__.__name__ for c in self.constraints)
def get_reduced_chemical_formula(atoms): numbers = atoms.numbers unique_numbers, counts = np.unique(numbers, return_counts=True) denominator = reduce(gcd, counts) reduced_numbers = [] for i, atomic_number in enumerate(unique_numbers): reduced_count = int(counts[i] / denominator) reduced_numbers += [atomic_number] * reduced_count return formula_metal(reduced_numbers)
def get_chemical_formula(self, mode='hill', empirical=False): """Get chemical formula. See documentation of ase.atoms.Atoms.get_chemical_formula().""" if mode in ('reduce', 'all') and empirical: warnings.warn("Empirical chemical formula not available " "for mode '{}'".format(mode)) if len(self) == 0: return '' numbers = self.numbers if mode == 'reduce': n = len(numbers) changes = np.concatenate( ([0], np.arange(1, n)[numbers[1:] != numbers[:-1]])) symbols = [chemical_symbols[e] for e in numbers[changes]] counts = np.append(changes[1:], n) - changes tokens = [] for s, c in zip(symbols, counts): tokens.append(s) if c > 1: tokens.append(str(c)) formula = ''.join(tokens) elif mode == 'hill': formula = formula_hill(numbers, empirical=empirical) elif mode == 'all': formula = ''.join([chemical_symbols[n] for n in numbers]) elif mode == 'metal': formula = formula_metal(numbers, empirical=empirical) else: raise ValueError("Use mode = 'all', 'reduce', 'hill' or 'metal'.") return formula
def formula(self): """Chemical formula string.""" return formula_metal(self.numbers)
def _formula(self): return formula_metal(self.numbers)
def __init__(self, row, meta={}, subscript=None, prefix='', tmpdir='.'): self.row = row self.cell = [['{:.3f}'.format(a) for a in axis] for axis in row.cell] par = ['{:.3f}'.format(x) for x in cell_to_cellpar(row.cell)] self.lengths = par[:3] self.angles = par[3:] forces = row.get('constrained_forces') if forces is None: fmax = None self.forces = None else: fmax = (forces**2).sum(1).max()**0.5 N = len(forces) self.forces = [] for n, f in enumerate(forces): if n < 5 or n >= N - 5: f = tuple('{0:10.3f}'.format(x) for x in f) symbol = chemical_symbols[row.numbers[n]] self.forces.append((n, symbol) + f) elif n == 5: self.forces.append( (' ...', '', ' ...', ' ...', ' ...')) self.stress = row.get('stress') if self.stress is not None: self.stress = ', '.join('{0:.3f}'.format(s) for s in self.stress) if 'masses' in row: mass = row.masses.sum() else: mass = atomic_masses[row.numbers].sum() self.formula = formula_metal(row.numbers) if subscript: self.formula = subscript.sub(r'<sub>\1</sub>', self.formula) age = float_to_time_string(now() - row.ctime, True) table = dict( (key, value) for key, value in [('id', row.id), ('age', age), ('formula', self.formula), ('user', row.user), ('calculator', row.get('calculator')), ( 'energy', row.get('energy')), ('fmax', fmax), ('charge', row.get('charge')), ('mass', mass), ('magmom', row.get('magmom')), ( 'unique id', row.unique_id), ('volume', row.get('volume'))] if value is not None) table.update(row.key_value_pairs) for key, value in table.items(): if isinstance(value, float): table[key] = '{:.3f}'.format(value) kd = meta.get('key_descriptions', {}) misc = set(table.keys()) self.layout = [] for headline, columns in meta['layout']: empty = True newcolumns = [] for column in columns: newcolumn = [] for block in column: if block is None: pass elif isinstance(block, tuple): title, keys = block rows = [] for key in keys: value = table.get(key, None) if value is not None: if key in misc: misc.remove(key) desc, unit = kd.get(key, [0, key, ''])[1:] rows.append((desc, value, unit)) if rows: block = (title, rows) else: continue elif any(block.endswith(ext) for ext in ['.png', '.csv']): name = op.join(tmpdir, prefix + block) if not op.isfile(name): self.create_figures(row, prefix, tmpdir, meta['functions']) if op.getsize(name) == 0: # Skip empty files: block = None elif block.endswith('.csv'): block = read_csv_table(name) else: assert block in ['ATOMS', 'CELL', 'FORCES'], block newcolumn.append(block) if block is not None: empty = False newcolumns.append(newcolumn) if not empty: self.layout.append((headline, newcolumns)) if misc: rows = [] for key in sorted(misc): value = table[key] desc, unit = kd.get(key, [0, key, ''])[1:] rows.append((desc, value, unit)) self.layout.append(('Miscellaneous', [[('Items', rows)]])) self.dipole = row.get('dipole') if self.dipole is not None: self.dipole = ', '.join('{0:.3f}'.format(d) for d in self.dipole) self.data = row.get('data') if self.data: self.data = ', '.join(self.data.keys()) self.constraints = row.get('constraints') if self.constraints: self.constraints = ', '.join(d['name'] for d in self.constraints)
def get_reduced_chemical_formula(atoms): numbers = atoms.numbers reduced_numbers, den = get_reduced_numbers(numbers) return formula_metal(reduced_numbers)