Source code for ase.io.xsd

# flake8: noqa
import numpy as np
import xml.etree.ElementTree as ET
from xml.dom import minidom

from ase.utils import basestring
from ase import Atoms


[docs]def read_xsd(fd): tree = ET.parse(fd) root = tree.getroot() atomtreeroot = root.find('AtomisticTreeRoot') # if periodic system if atomtreeroot.find('SymmetrySystem') is not None: symmetrysystem = atomtreeroot.find('SymmetrySystem') mappingset = symmetrysystem.find('MappingSet') mappingfamily = mappingset.find('MappingFamily') system = mappingfamily.find('IdentityMapping') coords = list() cell = list() formula = str() for atom in system: if atom.tag == 'Atom3d': symbol = atom.get('Components') formula += symbol xyz = atom.get('XYZ') if xyz: coord = [float(coord) for coord in xyz.split(',')] else: coord = [0.0, 0.0, 0.0] coords.append(coord) elif atom.tag == 'SpaceGroup': avec = [float(vec) for vec in atom.get('AVector').split(',')] bvec = [float(vec) for vec in atom.get('BVector').split(',')] cvec = [float(vec) for vec in atom.get('CVector').split(',')] cell.append(avec) cell.append(bvec) cell.append(cvec) atoms = Atoms(formula, cell=cell, pbc=True) atoms.set_scaled_positions(coords) return atoms # if non-periodic system elif atomtreeroot.find('Molecule') is not None: system = atomtreeroot.find('Molecule') coords = list() formula = str() for atom in system: if atom.tag == 'Atom3d': symbol = atom.get('Components') formula += symbol xyz = atom.get('XYZ') coord = [float(coord) for coord in xyz.split(',')] coords.append(coord) atoms = Atoms(formula, pbc=False) atoms.set_scaled_positions(coords) return atoms
def CPK_or_BnS(element): """Determine how atom is visualized""" if element in ['C', 'H', 'O', 'S', 'N']: visualization_choice = 'Ball and Stick' else: visualization_choice = 'CPK' return visualization_choice def SetChild(parent,childname,props): Child = ET.SubElement(parent,childname) for key in props: Child.set(key,props[key]) return Child def SetBasicChilds(): """ Basic property setup for Material Studio File """ XSD = ET.Element('XSD') XSD.set('Version', '6.0') ATR = SetChild(XSD,'AtomisticTreeRoot',{'ID':'1','NumProperties':'40','NumChildren':'1'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'AngleEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'BendBendEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'BendTorsionBendEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'BondEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'EFGAsymmetry','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'EFGQuadrupolarCoupling','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'ElectrostaticEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'GrowthFace','Name':'FaceMillerIndex','Type':'MillerIndex'}) SetChild(ATR,'Property',{'DefinedOn':'GrowthFace','Name':'FacetTransparency','Type':'Float'}) SetChild(ATR,'Property',{'DefinedOn':'Bondable','Name':'Force','Type':'CoDirection'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'HydrogenBondEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Bondable','Name':'ImportOrder','Type':'UnsignedInteger'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'InversionEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'IsBackboneAtom','Type':'Boolean'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'IsChiralCenter','Type':'Boolean'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'IsOutOfPlane','Type':'Boolean'}) SetChild(ATR,'Property',{'DefinedOn':'BestFitLineMonitor','Name':'LineExtentPadding','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Linkage','Name':'LinkageGroupName','Type':'String'}) SetChild(ATR,'Property',{'DefinedOn':'PropertyList','Name':'ListIdentifier','Type':'String'}) SetChild(ATR,'Property',{'DefinedOn':'Atom','Name':'NMRShielding','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'NonBondEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Bondable','Name':'NormalMode','Type':'Direction'}) SetChild(ATR,'Property',{'DefinedOn':'Bondable','Name':'NormalModeFrequency','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Bondable','Name':'OrbitalCutoffRadius','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'BestFitPlaneMonitor','Name':'PlaneExtentPadding','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'PotentialEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ScalarFieldBase','Name':'QuantizationValue','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'RestraintEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'SeparatedStretchStretchEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'Trajectory','Name':'SimulationStep','Type':'Integer'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'StretchBendStretchEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'StretchStretchEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'StretchTorsionStretchEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'TorsionBendBendEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'TorsionEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'TorsionStretchEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'ValenceCrossTermEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'ValenceDiagonalEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'ClassicalEnergyHolder','Name':'VanDerWaalsEnergy','Type':'Double'}) SetChild(ATR,'Property',{'DefinedOn':'SymmetrySystem','Name':'_Stress','Type':'Matrix'}) return ATR, XSD def _write_xsd_html(images,connectivity=None): ATR, XSD = SetBasicChilds() natoms = len(images[0]) atom_element = images[0].get_chemical_symbols() atom_cell = images[0].get_cell() atom_positions = images[0].get_positions() # Set up bonds bonds = list() if connectivity is not None: for i in range(connectivity.shape[0]): for j in range(i+1,connectivity.shape[0]): if connectivity[i,j]: bonds.append([i,j]) # non-periodic system if not images[0].pbc.all(): Molecule = SetChild(ATR,'Molecule',{'ID':'2','NumChildren':str(natoms+len(bonds)),'Name':'Lattice=&quot1.0'}) # writing images[0] for x in range(natoms): Props = {'ID': str(x + 3),'Name':(atom_element[x] + str(x + 1)),'UserID':str(x + 1),'DisplayStyle':CPK_or_BnS(atom_element[x])} Props['XYZ']='%1.16f,%1.16f,%1.16f' %(atom_positions[x,0],atom_positions[x,1],atom_positions[x,2]) Props['Components']=atom_element[x] bondstr = ['%i'% (i + 3 + natoms) for i,bond in enumerate(bonds) if x in bond] if bondstr: Props['Connections']=','.join(bondstr) SetChild(Molecule,'Atom3d',Props) for x in range(len(bonds)): SetChild(Molecule,'Bond',{'ID':str(x + 3 + natoms),'Connects':'%i,%i'%(bonds[x][0] + 3,bonds[x][1] + 3)}) # periodic system else: atom_positions = np.dot(atom_positions, np.linalg.inv(atom_cell)) Props = {} Props['ID']='2' Props['Mapping']= '3' Props['Children']= ''.join(['%1.0f,' % (x) for x in range(4, natoms + len(bonds) + 4)]+[str(natoms + len(bonds) + 4)]) Props['Normalized']= '1' Props['Name']= 'SymmSys' Props['UserID']= str(natoms + 18) Props['XYZ']= '0.00000000000000,0.00000000000000,0.000000000000000' Props['OverspecificationTolerance']= '0.05' Props['PeriodicDisplayType']= 'Original' SymmSys = SetChild(ATR,'SymmetrySystem',Props) Props = {} Props['ID']= str(natoms + len(bonds) + 5) Props['SymmetryDefinition']= str(natoms + 4) Props['ActiveSystem']= '2' Props['NumFamilies']= '1' Props['OwnsTotalConstraintMapping']= '1' Props['TotalConstraintMapping']= '3' MappngSet = SetChild(SymmSys, 'MappingSet',Props) Props = {} Props['ID']= str(natoms + len(bonds) + 6) Props['NumImageMappings']= '0' MappngFamily = SetChild(MappngSet, 'MappingFamily',Props) Props = {} Props['ID']= str(natoms + len(bonds) + 7) Props['Element']= '1,0,0,0,0,1,0,0,0,0,1,0' Props['Constraint']= '1,0,0,0,0,1,0,0,0,0,1,0' Props['MappedObjects']= ','.join(['%1.0f' % (x) for x in range(4, natoms + len(bonds) + 4)]) Props['DefectObjects']= str(natoms + len(bonds) + 4) + ',' + str(natoms + len(bonds) + 8) Props['NumImages']= str(natoms + len(bonds)) Props['NumDefects']= '2' IdentMappng = SetChild(MappngFamily, 'IdentityMapping',Props) SetChild(MappngFamily,'MappingRepairs',{'NumRepairs':'0'}) # writing atoms for x in range(natoms): Props = {} Props['ID']= str(x + 4) Props['Mapping']= str(natoms + len(bonds) + 7) Props['Parent']= '2' Props['Name']= (atom_element[x] + str(x + 1)) Props['UserID']= str(x + 1) Props['DisplayStyle']= CPK_or_BnS(atom_element[x]) Props['Components']= atom_element[x] Props['XYZ']='%1.16f,%1.16f,%1.16f' %(atom_positions[x,0],atom_positions[x,1],atom_positions[x,2]) bondstr = ['%i'% (i + 4 + natoms + 1) for i,bond in enumerate(bonds) if x in bond] if bondstr: Props['Connections']=','.join(bondstr) SetChild(IdentMappng, 'Atom3d',Props) for x in range(len(bonds)): SetChild(IdentMappng,'Bond',{'ID':str(x + 4 + natoms + 1),'Mapping':str(natoms + len(bonds) + 7), 'Parent':'2','Connects':'%i,%i'%(bonds[x][0] + 4,bonds[x][1] + 4)}) Props={} Props['ID']= str(natoms + 4) Props['Parent']= '2' Props['Children']= str(natoms + len(bonds) + 8) Props['DisplayStyle']= 'Solid' Props['XYZ']= '0.00,0.00,0.00' Props['Color']= '0,0,0,0' Props['AVector']= ','.join(['%1.16f' % atom_cell[0, x] for x in range(3)]) Props['BVector']= ','.join(['%1.16f' % atom_cell[1, x] for x in range(3)]) Props['CVector']= ','.join(['%1.16f' % atom_cell[2, x] for x in range(3)]) Props['OrientationBase']= 'C along Z, B in YZ plane' Props['Centering']= '3D Primitive-Centered' Props['Lattice']= '3D Triclinic' Props['GroupName']= 'GroupName' Props['Operators']= '1,0,0,0,0,1,0,0,0,0,1,0' Props['DisplayRange']= '0,1,0,1,0,1' Props['LineThickness']= '2' Props['CylinderRadius']= '0.2' Props['LabelAxes']= '1' Props['ActiveSystem']= '2' Props['ITNumber']= '1' Props['LongName']= 'P 1' Props['Qualifier']= 'Origin-1' Props['SchoenfliesName']= 'C1-1' Props['System']= 'Triclinic' Props['Class']= '1' SetChild(IdentMappng, 'SpaceGroup',Props) SetChild(IdentMappng, 'ReciprocalLattice3D',{'ID':str(natoms + len(bonds) + 8), 'Parent':str(natoms + 4)}) SetChild(MappngSet, 'InfiniteMapping',{'ID':'3','Element':'1,0,0,0,0,1,0,0,0,0,1,0', 'MappedObjects':'2'}) return XSD,ATR
[docs]def write_xsd(filename, images, connectivity=None): """Takes Atoms object, and write materials studio file atoms: Atoms object filename: path of the output file connectivity: number of atoms by number of atoms matrix for connectivity between atoms (0 not connected, 1 connected) note: material studio file cannot use a partial periodic system. If partial perodic system was inputted, full periodicity was assumed. """ if hasattr(images, 'get_positions'): images = [images] XSD,ATR = _write_xsd_html(images,connectivity) # check if file is an object or not. if isinstance(filename, basestring): f = open(filename, 'w') else: # Assume it's a 'file-like object' f = filename # Return a pretty-printed XML string for the Element. rough_string = ET.tostring(XSD, 'utf-8') reparsed = minidom.parseString(rough_string) Document = reparsed.toprettyxml(indent='\t') f.write(Document)