def ParseAtomSection(self): """Parse the ATOM section.""" if hasattr(self, "natoms"): atomicCharges = Real1DArray.WithExtent(self.natoms) atomicCharges.Set(0.0) atomicNumbers = [] atomNames = [] xyz = Coordinates3.WithExtent(self.natoms) xyz.Set(0.0) for i in range(self.natoms): items = self.GetTokens(converters=[ int, None, float, float, float, None, None, None, float ]) if len(items) < 6: self.Warning("Invalid ATOM line.", True) else: atomicNumber = PeriodicTable.AtomicNumber(items[1]) if atomicNumber <= 0: atomicNumber = self.AtomicNumberFromAtomType(items[5]) atomicNumbers.append(atomicNumber) atomNames.append(items[1]) xyz[i, 0] = items[2] xyz[i, 1] = items[3] xyz[i, 2] = items[4] if len(items) >= 9: atomicCharges[i] = items[8] self.atomicCharges = atomicCharges self.atomicNumbers = atomicNumbers self.atomNames = atomNames self.xyz = xyz else: self.Warning("Unknown number of atoms in molecule.", True)
def ParseGeometry(self): """Parse a geometry.""" self.GetLine() # .The Angstroms line. self.GetLine() # . The atoms heading. atomicNumbers = [] xyz = [] dummies = set() n = 0 while True: tokens = self.GetTokens() if (len(tokens) == 4): atomicNumber = PeriodicTable.AtomicNumber(tokens[0]) if (atomicNumber > 0): atomicNumbers.append(atomicNumber) x = float(tokens[1]) y = float(tokens[2]) z = float(tokens[3]) xyz.append((x, y, z)) else: dummies.add(n) n += 1 else: break if (len(atomicNumbers) > 0): self.atomicNumbers = atomicNumbers if self.coordinates3 is None: self.coordinates3 = Coordinates3.WithExtent(len(xyz)) for (i, (x, y, z)) in enumerate(xyz): self.coordinates3[i, 0] = x self.coordinates3[i, 1] = y self.coordinates3[i, 2] = z self.natoms = len(self.atomicNumbers) self.ngeometries += 1 self.dummies = dummies
def AtomicNumberFromAtomType(self, atomtype): """Get an atomic number from atom type.""" atomicNumber = -1 token = atomtype.split(".", 1)[0] if token not in _GENERICATOMTYPES: atomicNumber = PeriodicTable.AtomicNumber(token) return atomicNumber
def ParseZmatSection(self, line): """Parse the geometry (XYZ only for the moment).""" # . Get the terminator as the opening character of the current line. terminator = line[0:1] # . Initialization. atomicNumbers = [] xyz = [] nwarnings0 = self.nwarnings # . Loop until an end of section is reached. while True: items = self.GetTokens(converters=[ None, JaguarInputFileReader.ToFloat, JaguarInputFileReader.ToFloat, JaguarInputFileReader.ToFloat ]) # . The end found. if (len(items) == 1) and (items[0] == terminator): break # . An XYZ line. elif len(items) == 4: atomicNumber = PeriodicTable.AtomicNumber(items[0]) if atomicNumber > 0: atomicNumbers.append(atomicNumber) xyz.append((items[1], items[2], items[3])) # . Other lines. else: self.Warning("Unable to interpret geometry line.", True) # . Save the data if there have been no warnings. if nwarnings0 == self.nwarnings: self.atomicNumbers = atomicNumbers self.coordinates3 = Coordinates3.WithExtent(len(xyz)) for (i, (x, y, z)) in enumerate(xyz): self.coordinates3[i, 0] = x self.coordinates3[i, 1] = y self.coordinates3[i, 2] = z
def ParseMass(self, tokens): """Mass line.""" if len(tokens) < 3: self.Warning("Invalid MASS line.", False) else: index = int(tokens[0]) label = tokens[1] mass = float(tokens[2]) if len(tokens) > 3: atomicNumber = PeriodicTable.AtomicNumber(tokens[3]) else: atomicNumber = PeriodicTable.AtomicNumberFromMass(mass) self.atomTypes[label] = CHARMMTopologyAtomType( atomicNumber=atomicNumber, index=index, label=label, mass=mass)
def _ProcessRawData(self, bases): """Process the input basis lines.""" # . Process the text data. self.bases = [] for basis in bases: # . Title line. (iline, line) = basis.pop(0) words = line.split() atomicNumber = PeriodicTable.AtomicNumber(words[0]) if atomicNumber <= 0: self.Warning( "Invalid element, {:s}, for basis on line {:d}.".format( words[0], iline), True) # . Shell lines. shells = [] while len(basis) > 0: # . Header. (iline, line) = basis.pop(0) words = line.split() shellid = words[0].upper() if shellid not in _ShellTypes: self.Warning( "Unrecognized shell type, {:s}, for basis on line {:d}." .format(shellid, iline), True) nprimitives = int(words[1]) scale = float(words[2]) # . Primitive lines. primitives = [] if len(basis) >= nprimitives: for p in range(nprimitives): primitive = [] (iline, line) = basis.pop(0) words = line.split() if (len(words) != (len(shellid) + 1)): self.Warning( "Invalid number of primitive data on line {:d}." .format(iline), True) for word in words: primitive.append(float(word)) primitives.append(primitive) else: self.Warning( "Invalid number of primitives for basis on line {:d}.". format(iline), True) # . Save the data. shells.append((shellid, nprimitives, scale, primitives)) # . Save the basis. self.bases.append((atomicNumber, shells))
def ParseECPs(self): """Parse the ECP section.""" # . Initialization. ecpelectrons = [] # . Header. self.GetLine() # . Blank line. self.GetLine() # . Table header. # . Loop over atom lines. while True: tokens = self.GetTokens() # . Blank line. if len(tokens) == 0: break # . Atom line. elif len(tokens) == 2: atomicNumber = PeriodicTable.AtomicNumber(tokens[0]) if (atomicNumber > 0): ecpelectrons.append(int(tokens[1])) # . Finish up. self.ecpelectrons = ecpelectrons self.QECP = True
def GetAtomicNumber ( token ): """Convert a token into an atomic number.""" symbol = token.upper ( ) if symbol == _DUMMYATOM: return -3 elif symbol in _NONDUMMYATOMSYMBOLS: return -2 else: return PeriodicTable.AtomicNumber ( token )
def AddAtomSite(self, **kwargs): """Add an atom site.""" atom = None if self.QFINALIZED: raise ValueError("Cannot add an atom site to a finalized model.") else: # . Initialization. warningtag = "Atom Site {:d}".format(len(self.atoms)) # . Get the entity. auth_asym_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "auth_asym_id") label_asym_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_asym_id") label_entity_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_entity_id") entitykey = mmCIFModelEntity.MakeKey(label_entity_id, label_asym_id) entity = self.entities.get(entitykey, None) if entity is None: entity = self.AddEntity(entitykey) # . Check the alternate name. if entity is not None: if entity.alternateasymlabel is None: entity.alternateasymlabel = auth_asym_id elif entity.alternateasymlabel != auth_asym_id: self.Warning( warningtag, "Mismatch in alternate names for entity asymmetric unit - " + entity.alternateasymlabel + " and " + auth_asym_id + ".", False) # . Get the component. auth_comp_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "auth_comp_id") auth_seq_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "auth_seq_id") insertioncode = mmCIFModel.FetchFromKeywordArguments( kwargs, "pdbx_pdb_ins_code") name = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_comp_id") sequencenumber = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_seq_id") if name == _UNDEFINEDCHARACTER: name = auth_comp_id auth_comp_id = None if sequencenumber == _UNDEFINEDCHARACTER: sequencenumber = auth_seq_id auth_seq_id = None componentkey = mmCIFModelComponent.MakeKey( name, sequencenumber, insertioncode) component = entity.components.get(componentkey, None) if component is None: component = entity.AddComponent(componentkey) self.components.append(component) # . Check alternate names. if component is not None: if auth_comp_id is not None: if component.alternatename is None: component.alternatename = auth_comp_id elif component.alternatename != auth_comp_id: self.Warning( warningtag, "Mismatch in alternate names for component - " + component.alternatename + " and " + auth_comp_id + ".", False) if auth_seq_id is not None: if component.alternatesequence is None: component.alternatesequence = auth_seq_id elif component.alternatesequence != auth_seq_id: self.Warning( warningtag, "Mismatch in alternate sequences for component - " + component.alternatesequence + " and " + auth_seq_id + ".", False) # . Get the atom data. atomicNumber = PeriodicTable.AtomicNumber( mmCIFModel.FetchFromKeywordArguments( kwargs, "type_symbol")) auth_atom_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "auth_atom_id") name = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_atom_id") if name == _UNDEFINEDCHARACTER: name = auth_atom_id auth_atom_id = None atom = component.atoms.get(name, None) atomKey = name if atom is None: atom = component.AddAtom(name, atomicNumber=atomicNumber, entity=entity) self.atoms.append(atom) # . Check alternate labels. if atom is not None: if auth_comp_id is not None: if atom.alternatelabel is None: atom.alternatelabel = auth_atom_id elif atom.alternatelabel != auth_atom_id: self.Warning( warningtag, "Mismatch in alternate labels for atom - " + atom.alternatelabel + " and " + auth_atom_id + ".", False) # . Get the atom data. label_alt_id = mmCIFModel.FetchFromKeywordArguments( kwargs, "label_alt_id") pdbx_pdb_model_num = mmCIFModel.FetchFromKeywordArguments( kwargs, "pdbx_pdb_model_num", default=_DEFAULTMODELNUMBER) self.altLocs.add(label_alt_id) self.modelNumbers.add(pdbx_pdb_model_num) datakey = mmCIFModelAtomData.MakeKey( label_alt_id, pdbx_pdb_model_num) data = atom.data.get(datakey, None) if data is None: try: x = mmCIFModel.ToFloat( mmCIFModel.FetchFromKeywordArguments( kwargs, "cartn_x")) y = mmCIFModel.ToFloat( mmCIFModel.FetchFromKeywordArguments( kwargs, "cartn_y")) z = mmCIFModel.ToFloat( mmCIFModel.FetchFromKeywordArguments( kwargs, "cartn_z")) occupancy = mmCIFModel.ToFloat( mmCIFModel.FetchFromKeywordArguments( kwargs, "occupancy"), default=_DEFAULTOCCUPANCY) except: self.Warning( warningtag, "Unable to convert atom site floating point data.", False) atom.data[datakey] = mmCIFModelAtomData( altLoc=label_alt_id, atom=atom, model=pdbx_pdb_model_num, x=x, y=y, z=z, occupancy=occupancy) else: self.Warning( warningtag, "Adding duplicate atomsite (" + _MAJORSEPARATOR.join([ datakey, atomKey, componentkey, entitylabel ]) + ") to model.", False) return atom
def ParseAtomBlock(self, line, QLOOP): """Parse the block with atom information.""" # . Initialization. atoms = [] QFIRST = True if QLOOP: # . Initialization. index = {} converters = [] QATOMS = False # . Atom lines. while True: if not QFIRST: line = self.GetLine() if line.startswith("#"): break # . Column headers. elif not QATOMS: if line.startswith("_chem_comp_atom.atom_id"): index["atom_id"] = len(converters) converters.append(None) elif line.startswith("_chem_comp_atom.charge"): index["charge"] = len(converters) converters.append(int) elif line.startswith("_chem_comp_atom.comp_id"): index["comp_id"] = len(converters) converters.append(None) elif line.startswith("_chem_comp_atom.pdbx_align"): index["pdbx_align"] = len(converters) converters.append(int) elif line.startswith("_chem_comp_atom.type_symbol"): index["type_symbol"] = len(converters) converters.append(PeriodicTable.AtomicNumber) elif line.startswith("_chem_comp_atom."): converters.append(None) else: QATOMS = True # . Atoms. if QATOMS: tokens = self.ParseTokens(line, converters=converters) atoms.append ( PDBComponentAtom ( atomicNumber = tokens[index["type_symbol"]], \ formalCharge = tokens[index["charge" ]], \ label = tokens[index["atom_id" ]], \ pdbAlign = tokens[index["pdbx_align" ]] ) ) QFIRST = False # . Single atom. else: while True: if not QFIRST: line = self.GetLine() tokens = self.ParseTokens(line) if tokens[0] == "#": break elif len(tokens) > 2: self.Warning("Too many tokens.", True) elif tokens[0] == "_chem_comp_atom.atom_id": label = tokens[1] elif tokens[0] == "_chem_comp_atom.charge": formalCharge = int(tokens[1]) elif tokens[0] == "_chem_comp_atom.pdbx_align": pdbAlign = int(tokens[1]) elif tokens[0] == "_chem_comp_atom.type_symbol": atomicNumber = PeriodicTable.AtomicNumber(tokens[1]) QFIRST = False atoms.append ( PDBComponentAtom ( atomicNumber = atomicNumber, \ formalCharge = formalCharge, \ label = label, \ pdbAlign = pdbAlign ) ) # . Finish up. self.active.atoms = atoms