public IEnumerable <IAtomType> FindMatchingAtomTypes(IAtomContainer atomContainer) { foreach (var atom in atomContainer.Atoms) { var type = cdkMatcher.FindMatchingAtomType(atomContainer, atom); atom.AtomTypeName = type?.AtomTypeName; atom.Hybridization = type == null ? Hybridization.Unset : type.Hybridization; } Aromaticity.CDKLegacy.Apply(atomContainer); int typeCounter = 0; foreach (var atom in atomContainer.Atoms) { string mappedType = MapCDKToSybylType(atom); if (mappedType == null) { yield return(null); } else { yield return(factory.GetAtomType(mappedType)); } typeCounter++; } yield break; }
/// <inheritdoc/> public bool IsSaturated(IAtom atom, IAtomContainer ac) { var atomType = factory.GetAtomType(atom.AtomTypeName); var lpCount = atomType.GetProperty <int>(CDKPropertyName.LonePairCount); var foundLPCount = ac.GetConnectedLonePairs(atom).Count(); return(foundLPCount >= lpCount); }
/// <summary> /// get the electrostatic potential of the neighbours of a atom. /// </summary> /// <param name="ac">The IAtomContainer to study</param> /// <param name="atom1">The position of the IAtom to study</param> /// <param name="ds"></param> /// <returns>The sum of electrostatic potential of the neighbours</returns> private double GetElectrostaticPotentialN(IAtomContainer ac, int atom1, double[] ds) { // double CoulombForceConstant = 1/(4*Math.PI*8.81/*Math.Pow(10, -12)*/); double CoulombForceConstant = 0.048; double sum = 0.0; try { var atoms = ac.GetConnectedAtoms(ac.Atoms[atom1]); foreach (var atom in atoms) { double covalentradius = 0; string symbol = atom.Symbol; IAtomType type = factory.GetAtomType(symbol); covalentradius = type.CovalentRadius.Value; double charge = ds[StepSize * atom1 + atom1 + 5]; Debug.WriteLine($"sum_({sum}) = CFC({CoulombForceConstant})*Charge({charge}/ret({covalentradius}"); sum += CoulombForceConstant * charge / (covalentradius * covalentradius); } } catch (CDKException e) { Debug.WriteLine(e); } return(sum); }
public bool IsSaturated(IAtom atom, IAtomContainer container) { var type = atomTypeList.GetAtomType(atom.AtomTypeName); if (type == null) { throw new CDKException($"Atom type is not a recognized CDK atom type: {atom.AtomTypeName}"); } if (type.FormalNeighbourCount == null) { throw new CDKException($"Atom type is too general; cannot decide the number of implicit hydrogen to add for: {atom.AtomTypeName}"); } if (type.GetProperty <object>(CDKPropertyName.PiBondCount) == null) { throw new CDKException($"Atom type is too general; cannot determine the number of pi bonds for: {atom.AtomTypeName}"); } var bondOrderSum = container.GetBondOrderSum(atom); var maxBondOrder = container.GetMaximumBondOrder(atom); int?hcount = atom.ImplicitHydrogenCount == null ? 0 : atom.ImplicitHydrogenCount; int piBondCount = type.GetProperty <int?>(CDKPropertyName.PiBondCount).Value; int formalNeighborCount = type.FormalNeighbourCount.Value; int typeMaxBondOrder = piBondCount + 1; int typeBondOrderSum = formalNeighborCount + piBondCount; if (bondOrderSum + hcount == typeBondOrderSum && maxBondOrder.Numeric() <= typeMaxBondOrder) { return(true); } return(false); }
/// <inheritdoc/> public void AddImplicitHydrogens(IAtomContainer container, IAtom atom) { if (atom.AtomTypeName == null) { throw new CDKException("IAtom is not typed! " + atom.Symbol); } if (string.Equals("X", atom.AtomTypeName, StringComparison.Ordinal)) { if (atom.ImplicitHydrogenCount == null) { atom.ImplicitHydrogenCount = 0; } return; } var type = atomTypeList.GetAtomType(atom.AtomTypeName); if (type == null) { throw new CDKException("Atom type is not a recognized CDK atom type: " + atom.AtomTypeName); } if (type.FormalNeighbourCount == null) { throw new CDKException($"Atom type is too general; cannot decide the number of implicit hydrogen to add for: {atom.AtomTypeName}"); } // very simply counting: each missing explicit neighbor is a missing hydrogen atom.ImplicitHydrogenCount = type.FormalNeighbourCount - container.GetConnectedBonds(atom).Count(); }
/// <summary> /// Calculates the volume for the given <see cref="IAtomContainer"/>. This methods assumes /// that atom types have been perceived. /// </summary> /// <param name="molecule"><see cref="IAtomContainer"/> to calculate the volume of.</param> /// <returns>the volume in cubic Ångström.</returns> public static double Calculate(IAtomContainer molecule) { double sum = 0.0; int totalHCount = 0; foreach (var atom in molecule.Atoms) { if (!bondiiVolumes.TryGetValue(atom.Symbol, out double bondiiVolume)) { throw new CDKException("Unsupported element."); } sum += bondiiVolume; // add volumes of implicit hydrogens? var type = atomTypeList.GetAtomType(atom.AtomTypeName); if (type == null) { throw new CDKException($"Unknown atom type for atom: {atom.Symbol}"); } if (type.FormalNeighbourCount == null) { throw new CDKException($"Formal neighbor count not given for : {type.AtomTypeName}"); } int hCount = type.FormalNeighbourCount.Value - molecule.GetConnectedBonds(atom).Count(); sum += hCount * bondiiVolumes["H"]; totalHCount += hCount; } sum -= 5.92 * (molecule.Bonds.Count + totalHCount); Aromaticity.CDKLegacy.Apply(molecule); var ringSet = Cycles.FindSSSR(molecule).ToRingSet(); if (ringSet.Count() > 0) { int aromRingCount = 0; int nonAromRingCount = 0; foreach (var ring in ringSet) { if (RingIsAromatic(ring)) { aromRingCount++; } else { nonAromRingCount++; } } sum -= 14.7 * aromRingCount; sum -= 3.8 * nonAromRingCount; } return(sum); }
/// <summary> /// Read a Reaction from a file in MDL RXN format /// </summary> /// <returns>The Reaction that was read from the MDL file.</returns> private IAtomContainer ReadMolecule(IAtomContainer molecule) { try { int atomCount = 0; int bondCount = 0; string line; while (true) { line = input.ReadLine(); if (line == null) { return(null); } if (line.StartsWith("@<TRIPOS>MOLECULE", StringComparison.Ordinal)) { break; } if (!line.StartsWithChar('#') && line.Trim().Length > 0) { break; } } // ok, if we're coming from the chemfile function, we've already read the molecule RTI if (firstLineisMolecule) { molecule.Title = line; } else { line = input.ReadLine(); molecule.Title = line; } // get atom and bond counts var counts = input.ReadLine(); var tokenizer = Strings.Tokenize(counts); try { atomCount = int.Parse(tokenizer[0], NumberFormatInfo.InvariantInfo); } catch (FormatException nfExc) { string error = "Error while reading atom count from MOLECULE block"; Trace.TraceError(error); Debug.WriteLine(nfExc); throw new CDKException(error, nfExc); } if (tokenizer.Count > 1) { try { bondCount = int.Parse(tokenizer[1], NumberFormatInfo.InvariantInfo); } catch (FormatException nfExc) { string error = "Error while reading atom and bond counts"; Trace.TraceError(error); Debug.WriteLine(nfExc); throw new CDKException(error, nfExc); } } else { bondCount = 0; } Trace.TraceInformation("Reading #atoms: ", atomCount); Trace.TraceInformation("Reading #bonds: ", bondCount); // we skip mol type, charge type and status bit lines Trace.TraceWarning("Not reading molecule qualifiers"); line = input.ReadLine(); bool molend = false; while (line != null) { if (line.StartsWith("@<TRIPOS>MOLECULE", StringComparison.Ordinal)) { molend = true; break; } else if (line.StartsWith("@<TRIPOS>ATOM", StringComparison.Ordinal)) { Trace.TraceInformation("Reading atom block"); for (int i = 0; i < atomCount; i++) { line = input.ReadLine().Trim(); if (line.StartsWith("@<TRIPOS>MOLECULE", StringComparison.Ordinal)) { molend = true; break; } tokenizer = Strings.Tokenize(line); // disregard the id token var nameStr = tokenizer[1]; var xStr = tokenizer[2]; var yStr = tokenizer[3]; var zStr = tokenizer[4]; var atomTypeStr = tokenizer[5]; // replace unrecognised atom type if (ATOM_TYPE_ALIASES.ContainsKey(atomTypeStr)) { atomTypeStr = ATOM_TYPE_ALIASES[atomTypeStr]; } var atom = molecule.Builder.NewAtom(); IAtomType atomType; try { atomType = atFactory.GetAtomType(atomTypeStr); } catch (Exception) { // ok, *not* an mol2 atom type atomType = null; } // Maybe it is just an element if (atomType == null && IsElementSymbol(atomTypeStr)) { atom.Symbol = atomTypeStr; } else { if (atomType == null) { atomType = atFactory.GetAtomType("X"); Trace.TraceError($"Could not find specified atom type: {atomTypeStr}"); } AtomTypeManipulator.Configure(atom, atomType); } atom.AtomicNumber = ChemicalElement.OfSymbol(atom.Symbol).AtomicNumber; atom.Id = nameStr; atom.AtomTypeName = atomTypeStr; try { var x = double.Parse(xStr, NumberFormatInfo.InvariantInfo); var y = double.Parse(yStr, NumberFormatInfo.InvariantInfo); var z = double.Parse(zStr, NumberFormatInfo.InvariantInfo); atom.Point3D = new Vector3(x, y, z); } catch (FormatException nfExc) { string error = "Error while reading atom coordinates"; Trace.TraceError(error); Debug.WriteLine(nfExc); throw new CDKException(error, nfExc); } molecule.Atoms.Add(atom); } } else if (line.StartsWith("@<TRIPOS>BOND", StringComparison.Ordinal)) { Trace.TraceInformation("Reading bond block"); for (int i = 0; i < bondCount; i++) { line = input.ReadLine(); if (line.StartsWith("@<TRIPOS>MOLECULE", StringComparison.Ordinal)) { molend = true; break; } tokenizer = Strings.Tokenize(line); // disregard the id token var atom1Str = tokenizer[1]; var atom2Str = tokenizer[2]; var orderStr = tokenizer[3]; try { var atom1 = int.Parse(atom1Str, NumberFormatInfo.InvariantInfo); var atom2 = int.Parse(atom2Str, NumberFormatInfo.InvariantInfo); if (string.Equals("nc", orderStr, StringComparison.Ordinal)) { // do not connect the atoms } else { var bond = molecule.Builder.NewBond(molecule.Atoms[atom1 - 1], molecule.Atoms[atom2 - 1]); switch (orderStr) { case "1": bond.Order = BondOrder.Single; break; case "2": bond.Order = BondOrder.Double; break; case "3": bond.Order = BondOrder.Triple; break; case "am": case "ar": bond.Order = BondOrder.Single; bond.IsAromatic = true; bond.Begin.IsAromatic = true; bond.End.IsAromatic = true; break; case "du": bond.Order = BondOrder.Single; break; case "un": bond.Order = BondOrder.Single; break; default: break; } molecule.Bonds.Add(bond); } } catch (FormatException nfExc) { var error = "Error while reading bond information"; Trace.TraceError(error); Debug.WriteLine(nfExc); throw new CDKException(error, nfExc); } } } if (molend) { return(molecule); } line = input.ReadLine(); } } catch (IOException exception) { var error = "Error while reading general structure"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } return(molecule); }
/// <summary> /// Gets the atomicSoftnessCore attribute of the InductivePartialCharges object. /// </summary> /// <remarks> /// this method returns the result of the core of the equation of atomic softness /// that can be used for qsar descriptors and during the iterative calculation /// of effective electronegativity /// </remarks> /// <param name="ac">AtomContainer</param> /// <param name="atomPosition">position of target atom</param> /// <returns>The atomicSoftnessCore value</returns> /// <exception cref="CDKException"></exception> public double GetAtomicSoftnessCore(IAtomContainer ac, int atomPosition) { IAtom target = null; double core = 0; double radiusTarget = 0; target = ac.Atoms[atomPosition]; double partial = 0; double radius = 0; IAtomType type = null; try { type = factory.GetAtomType(ac.Atoms[atomPosition].Symbol); var n = ac.Atoms[atomPosition].AtomicNumber; if (GetCovalentRadius(n, ac.GetMaximumBondOrder(target)) > 0) { radiusTarget = GetCovalentRadius(n, ac.GetMaximumBondOrder(target)); } else { radiusTarget = type.CovalentRadius.Value; } } catch (Exception ex1) { Debug.WriteLine(ex1); throw new CDKException("Problems with AtomTypeFactory due to " + ex1.Message, ex1); } foreach (var atom in ac.Atoms) { if (!target.Equals(atom)) { partial = 0; try { type = factory.GetAtomType(atom.Symbol); } catch (Exception ex1) { Debug.WriteLine(ex1); throw new CDKException($"Problems with AtomTypeFactory due to {ex1.Message}", ex1); } if (GetCovalentRadius(atom.AtomicNumber, ac.GetMaximumBondOrder(atom)) > 0) { radius = GetCovalentRadius(atom.AtomicNumber, ac.GetMaximumBondOrder(atom)); } else { radius = type.CovalentRadius.Value; } partial += radius * radius; partial += (radiusTarget * radiusTarget); partial = partial / (CalculateSquaredDistanceBetweenTwoAtoms(target, atom)); core += partial; } } core = 2 * core; core = 0.172 * core; return(core); }