def write_pdb(fileobj, images): """Write images to PDB-file. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] if images[0].get_pbc().any(): from ase.lattice.spacegroup.cell import cell_to_cellpar cellpar = cell_to_cellpar( images[0].get_cell()) # ignoring Z-value, using P1 since we have all atoms defined explicitly format = 'CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1\n' fileobj.write(format % (cellpar[0], cellpar[1], cellpar[2], cellpar[3], cellpar[4], cellpar[5])) # 1234567 123 6789012345678901 89 67 456789012345678901234567 890 format = 'ATOM %5d %4s MOL 1 %8.3f%8.3f%8.3f 1.00 0.00 %2s \n' # RasMol complains if the atom index exceeds 100000. There might # be a limit of 5 digit numbers in this field. MAXNUM = 100000 symbols = images[0].get_chemical_symbols() natoms = len(symbols) for n,atoms in enumerate(images): fileobj.write('MODEL '+str(n+1)+'\n') p = atoms.get_positions() for a in range(natoms): x, y, z = p[a] fileobj.write(format % (a % MAXNUM, symbols[a], x, y, z, symbols[a].rjust(2))) fileobj.write('ENDMDL\n')
def get_string(self, significant_figures=6, write_info=False): """ Returns a string to be written as a Res file. Args: significant_figures (int): No. of significant figures to output all quantities. Defaults to 6. write_info (bool): if True, format TITL line using key-value pairs from atoms.info in addition to attributes stored in Res object Returns: String representation of Res. """ # Title line if write_info: info = self.atoms.info.copy() for attribute in ['name', 'pressure', 'energy', 'spacegroup', 'times_found']: if getattr(self, attribute) and attribute not in info: info[attribute] = getattr(self, attribute) lines = ['TITL ' + ' '.join(['{0}={1}'.format(k, v) for (k, v) in info.items()])] else: lines = ['TITL ' + self.print_title()] # Cell abc_ang = cell_to_cellpar(self.atoms.get_cell()) fmt = '{{0:.{0}f}}'.format(significant_figures) cell = ' '.join([fmt.format(a) for a in abc_ang]) lines.append('CELL 1.0 ' + cell) # Latt lines.append('LATT -1') # Atoms symbols = self.atoms.get_chemical_symbols() species_types = [] for symbol in symbols: if symbol not in species_types: species_types.append(symbol) lines.append('SFAC ' + ' '.join(species_types)) fmt = '{{0}} {{1}} {{2:.{0}f}} {{3:.{0}f}} {{4:.{0}f}} 1.0' fmtstr = fmt.format(significant_figures) for symbol, coords in zip(symbols, self.atoms_.get_positions()): lines.append( fmtstr.format(symbol, species_types.index(symbol) + 1, coords[0], coords[1], coords[2])) lines.append('END') return '\n'.join(lines)
def export_to_vft(self, fname=None): #f = open(fname, "wb") import ase.data import StringIO import numpy as np import ase.lattice.spacegroup.cell as cell def shrink_list(nums): start = nums[0] end = nums[0] output = "" step = 1 for i in range(1, len(nums)): if nums[i] == start + step: end = nums[i] step += 1 else: end = nums[i - 1] if start == end: output += ("" if output == "" else ",") + str(start) else: output += ("" if output == "" else ",") + str(start) + ":" + str(end) start = nums[i] end = nums[i] step = 1 if (i == len(nums) - 1): if start == end: output += ("" if output == "" else ",") + str(start) else: output += ("" if output == "" else ",") + str(start) + ":" + str(end) return output output = StringIO.StringIO() output.write("# STRUCTURE BLOCK\n") #atom 0,2,4 radius 1.0 name N for t in range(len(self.ordering)): w_ids = shrink_list(self.ordering[t]) at_num = self.struct.get_ase().get_atomic_numbers()[ self.ordering[t][0]] w_radius = ase.data.vdw.vdw_radii[at_num] w_name = ase.data.chemical_symbols[at_num] if np.isnan(w_radius): w_radius = ase.data.covalent_radii[at_num] output.write( "atom {0} radius {1} name {2} atomicnumber {3}\n".format( w_ids, w_radius, w_name, t)) output.write("# TIMESTEP BLOCKS\n") for i in range(len(self.pos)): w_cell = " ".join([ "{0:.8f}".format(ap) for ap in cell.cell_to_cellpar(self.cells[i]) ]) output.write("timestep\n") output.write("pbc {0}\n".format(w_cell)) for kind_order in self.ordering: for o in kind_order: ordered_pos = self.pos[i][o] a_pos = " ".join( ["{0:.8f}".format(ap) for ap in ordered_pos]) output.write("{0}\n".format(a_pos)) try: if not fname == None: f = open(fname, 'wb') f.write(output.getvalue()) f.close() else: return output.getvalue() except: return None finally: output.close()
def write_reactant_con(fileobj, images): """Writes structure to EON reactant.con file Multiple snapshots are not allowed.""" if isinstance(fileobj, str): f = paropen(fileobj, 'w') else: f = fileobj if isinstance(images, Atoms): atoms = images elif len(images) == 1: atoms = images[0] else: raise ValueError('Can only write one configuration to EON ' 'reactant.con file') out = [] out.append(atoms.info.get('comment', 'Generated by ASE')) out.append('0.0000 TIME') # ?? a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.cell) out.append('%-10.6f %-10.6f %-10.6f' % (a, b, c)) out.append('%-10.6f %-10.6f %-10.6f' % (alpha, beta, gamma)) out.append('0 0') # ?? out.append('0 0 0') # ?? symbols = atoms.get_chemical_symbols() massdict = dict(zip(symbols, atoms.get_masses())) atomtypes = sorted(massdict.keys()) atommasses = [massdict[at] for at in atomtypes] natoms = [symbols.count(at) for at in atomtypes] ntypes = len(atomtypes) out.append(str(ntypes)) out.append(' '.join([str(n) for n in natoms])) out.append(' '.join([str(n) for n in atommasses])) for n in range(ntypes): out.append(atomtypes[n]) out.append('Coordinates of Component %d' % (n + 1)) indices = [i for i, at in enumerate(symbols) if at == atomtypes[n]] a = atoms[indices] coords = a.positions for c in a.constraints: if not isinstance(c, FixAtoms): warn('Only FixAtoms constraints are supported by con files. ' 'Dropping %r', c) continue if c.index.dtype.kind == 'b': fixed = np.array(c.index, dtype=int) else: fixed = np.zeros((natoms[n], ), dtype=int) for i in c.index: fixed[i] = 1 for i, (xyz, fix) in enumerate(zip(coords, fixed)): out.append('%10.5f %10.5f %10.5f %d %d' % (tuple(xyz) + (fix, i))) f.write('\n'.join(out)) if isinstance(fileobj, str): f.close()
def write(self, atoms=None, frame=None, arrays=None, time=None): """ Write the atoms to the file. If the atoms argument is not given, the atoms object specified when creating the trajectory object is used. """ self._open() self._call_observers(self.pre_observers) if atoms is None: atoms = self.atoms if hasattr(atoms, 'interpolate'): # seems to be a NEB neb = atoms assert not neb.parallel try: neb.get_energies_and_forces(all=True) except AttributeError: pass for image in neb.images: self.write(image) return if not self.has_header: self._define_file_structure(atoms) else: if len(atoms) != self.n_atoms: raise ValueError('Bad number of atoms!') if frame is None: i = self.frame else: i = frame # Number can be per file variable numbers = self._get_variable(self._numbers_var) if numbers.dimensions[0] == self._frame_dim: numbers[i] = atoms.get_atomic_numbers() else: if np.any(numbers != atoms.get_atomic_numbers()): raise ValueError('Atomic numbers do not match!') self._get_variable(self._positions_var)[i] = atoms.get_positions() if atoms.has('momenta'): self._add_velocities() self._get_variable(self._velocities_var)[i] = \ atoms.get_momenta() / atoms.get_masses().reshape(-1, 1) a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.get_cell()) cell_lengths = np.array([a, b, c]) * atoms.pbc self._get_variable(self._cell_lengths_var)[i] = cell_lengths self._get_variable(self._cell_angles_var)[i] = [alpha, beta, gamma] if arrays is not None: for array in arrays: data = atoms.get_array(array) if array in self.extra_per_file_vars: # This field exists but is per file data. Check that the # data remains consistent. if np.any(self._get_variable(array) != data): raise ValueError('Trying to write Atoms object with ' 'incompatible data for the {} ' 'array.'.format(array)) else: self._add_array(atoms, array, data.dtype, data.shape) self._get_variable(array)[i] = data if time is not None: self._add_time() self._get_variable(self._time_var)[i] = time self._call_observers(self.post_observers) self.frame += 1 self._close()
def write(self, atoms=None, frame=None, arrays=None, time=None): """ Write the atoms to the file. If the atoms argument is not given, the atoms object specified when creating the trajectory object is used. """ self._open() self._call_observers(self.pre_observers) if atoms is None: atoms = self.atoms if hasattr(atoms, 'interpolate'): # seems to be a NEB neb = atoms assert not neb.parallel try: neb.get_energies_and_forces(all=True) except AttributeError: pass for image in neb.images: self.write(image) return if not self.has_header: self._write_header(atoms) else: if len(atoms) != self.n_atoms: raise ValueError('Bad number of atoms!') if self.frame > 0: if (atoms.numbers != self.numbers).any(): raise ValueError('Bad atomic numbers!') else: self.numbers = atoms.get_atomic_numbers() self._get_variable(self._numbers_var)[:] = \ atoms.get_atomic_numbers() if frame is None: i = self.frame else: i = frame self._get_variable(self._positions_var)[i] = atoms.get_positions() if atoms.has('momenta'): self._add_velocities() self._get_variable(self._velocities_var)[i] = \ atoms.get_momenta() / atoms.get_masses().reshape(-1, 1) a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.get_cell()) cell_lengths = np.array([a, b, c]) * atoms.pbc self._get_variable(self._cell_lengths_var)[i] = cell_lengths self._get_variable(self._cell_angles_var)[i] = [alpha, beta, gamma] if arrays is not None: for array in arrays: data = atoms.get_array(array) self._add_array(atoms, array, data.dtype, data.shape) self._get_variable(array)[i] = data if time is not None: self._get_variable(self._time_var)[i] = time self._call_observers(self.post_observers) self.frame += 1 self._close()
def write_reactant_con(fileobj, images): """Writes structure to EON reactant.con file Multiple snapshots are not allowed.""" if isinstance(fileobj, str): f = paropen(fileobj, "w") else: f = fileobj if isinstance(images, Atoms): atoms = images elif len(images) == 1: atoms = images[0] else: raise ValueError("Can only write one configuration to EON " "reactant.con file") out = [] out.append(atoms.info.get("comment", "Generated by ASE")) out.append("0.0000 TIME") # ?? a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.cell) out.append("%-10.6f %-10.6f %-10.6f" % (a, b, c)) out.append("%-10.6f %-10.6f %-10.6f" % (gamma, beta, alpha)) out.append("0 0") # ?? out.append("0 0 0") # ?? symbols = atoms.get_chemical_symbols() massdict = dict(list(zip(symbols, atoms.get_masses()))) atomtypes = sorted(massdict.keys()) atommasses = [massdict[at] for at in atomtypes] natoms = [symbols.count(at) for at in atomtypes] ntypes = len(atomtypes) out.append(str(ntypes)) out.append(" ".join([str(n) for n in natoms])) out.append(" ".join([str(n) for n in atommasses])) atom_id = 0 for n in range(ntypes): fixed = np.array([False] * len(atoms)) out.append(atomtypes[n]) out.append("Coordinates of Component %d" % (n + 1)) indices = [i for i, at in enumerate(symbols) if at == atomtypes[n]] a = atoms[indices] coords = a.positions for c in a.constraints: if not isinstance(c, FixAtoms): warn("Only FixAtoms constraints are supported by con files. " "Dropping %r", c) continue if c.index.dtype.kind == "b": fixed = np.array(c.index, dtype=int) else: fixed = np.zeros((natoms[n],), dtype=int) for i in c.index: fixed[i] = 1 for xyz, fix in zip(coords, fixed): out.append("%22.17f %22.17f %22.17f %d %4d" % (tuple(xyz) + (fix, atom_id))) atom_id += 1 f.write("\n".join(out)) f.write("\n") if isinstance(fileobj, str): f.close()