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); }
/// <summary> /// Determines if the atom can be of type <see cref="IAtomType"/>. That is, it sees if this /// <see cref="IAtomType"/> only differs in bond orders, or implicit hydrogen count. /// </summary> private static bool CouldMatchAtomType(IAtomContainer container, IAtom atom, IAtomType type) { var bondOrderSum = container.GetBondOrderSum(atom); var maxBondOrder = container.GetMaximumBondOrder(atom); return(CouldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)); }
/// <summary> /// Checks if the current atom has exceeded its bond order sum value. /// </summary> /// <param name="atom">The Atom to check</param> /// <param name="ac">The atom container context</param> /// <returns>oversaturated or not</returns> public bool IsOverSaturated(IAtom atom, IAtomContainer ac) { var atomTypes = structgenATF.GetAtomTypes(atom.Symbol); if (!atomTypes.Any()) { return(false); } var bondOrderSum = ac.GetBondOrderSum(atom); var maxBondOrder = ac.GetMaximumBondOrder(atom); var hcount = atom.ImplicitHydrogenCount ?? 0; var charge = atom.FormalCharge ?? 0; try { Debug.WriteLine($"*** Checking saturation of atom {ac.Atoms.IndexOf(atom)} ***"); Debug.WriteLine($"bondOrderSum: {bondOrderSum}"); Debug.WriteLine($"maxBondOrder: {maxBondOrder}"); Debug.WriteLine($"hcount: {hcount}"); } catch (Exception) { } foreach (var atomType in atomTypes) { if (bondOrderSum - charge + hcount > atomType.BondOrderSum) { Debug.WriteLine("*** Good ! ***"); return(true); } } Debug.WriteLine("*** Bad ! ***"); return(false); }
/// <summary> /// Checks whether an atom is saturated by comparing it with known atom types. /// </summary> /// <returns><see langword="true"/> if the atom is an pseudo atom and when the element is not in the list.</returns> public bool IsSaturated(IAtom atom, IAtomContainer container) { if (atom is IPseudoAtom) { Debug.WriteLine("don't figure it out... it simply does not lack H's"); return(true); } var atomTypes = structgenATF.GetAtomTypes(atom.Symbol); if (atomTypes.Any()) { Trace.TraceWarning($"Missing entry in atom type list for {atom.Symbol}"); return(true); } var bondOrderSum = container.GetBondOrderSum(atom); var maxBondOrder = container.GetMaximumBondOrder(atom); var hcount = atom.ImplicitHydrogenCount.Value; var charge = atom.FormalCharge.Value; Debug.WriteLine($"Checking saturation of atom {atom.Symbol}"); Debug.WriteLine($"bondOrderSum: {bondOrderSum}"); Debug.WriteLine($"maxBondOrder: {maxBondOrder}"); Debug.WriteLine($"hcount: {hcount}"); Debug.WriteLine($"charge: {charge}"); bool elementPlusChargeMatches = false; foreach (var type in atomTypes) { if (CouldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)) { if (bondOrderSum + hcount == type.BondOrderSum && !BondManipulator.IsHigherOrder(maxBondOrder, type.MaxBondOrder)) { Debug.WriteLine($"We have a match: {type}"); Debug.WriteLine($"Atom is saturated: {atom.Symbol}"); return(true); } else { // ok, the element and charge matche, but unfulfilled elementPlusChargeMatches = true; } } // else: formal charges don't match } if (elementPlusChargeMatches) { Debug.WriteLine("No, atom is not saturated."); return(false); } // ok, the found atom was not in the list Trace.TraceError("Could not find atom type!"); throw new CDKException($"The atom with element {atom.Symbol} and charge {charge} is not found."); }
/// <summary> /// Checks whether an atom is saturated by comparing it with known atom types. /// </summary> public bool IsSaturated(IAtom atom, IAtomContainer ac) { var atomTypes = structgenATF.GetAtomTypes(atom.Symbol); if (!atomTypes.Any()) { return(true); } double bondOrderSum = 0; var maxBondOrder = BondOrder.Unset; int hcount = 0; int charge = 0; bool isInited = false; foreach (var atomType in atomTypes) { if (!isInited) { isInited = true; bondOrderSum = ac.GetBondOrderSum(atom); maxBondOrder = ac.GetMaximumBondOrder(atom); hcount = atom.ImplicitHydrogenCount ?? 0; charge = atom.FormalCharge ?? 0; try { Debug.WriteLine($"*** Checking saturation of atom {atom.Symbol} {ac.Atoms.IndexOf(atom)} ***"); Debug.WriteLine($"bondOrderSum: {bondOrderSum}"); Debug.WriteLine($"maxBondOrder: {maxBondOrder}"); Debug.WriteLine($"hcount: {hcount}"); } catch (Exception exc) { Debug.WriteLine(exc); } } if (bondOrderSum - charge + hcount == atomType.BondOrderSum && !BondManipulator.IsHigherOrder(maxBondOrder, atomType.MaxBondOrder)) { Debug.WriteLine("*** Good ! ***"); return(true); } } Debug.WriteLine("*** Bad ! ***"); return(false); }
private static void SetActiveCenters(IAtomContainer reactant, int length, bool checkPrev, AtomCheck atomCheck) { var hcg = new HOSECodeGenerator(); foreach (var atomi in reactant.Atoms) { if (reactant.GetConnectedSingleElectrons(atomi).Count() == 1) { IEnumerable <IAtom> atom1s = null; if (checkPrev) { hcg.GetSpheres(reactant, atomi, length - 1, true); atom1s = hcg.GetNodesInSphere(length - 1); } hcg.GetSpheres(reactant, atomi, length, true); foreach (var atoml in hcg.GetNodesInSphere(length)) { if (atoml != null && !atoml.IsInRing && (atoml.FormalCharge ?? 0) == 0 && !atoml.AtomicNumber.Equals(AtomicNumbers.H) && reactant.GetMaximumBondOrder(atoml) == BondOrder.Single) { foreach (var atomR in reactant.GetConnectedAtoms(atoml)) { if (atom1s != null && atom1s.Contains(atomR)) { continue; } if (atomCheck(atomR)) { atomi.IsReactiveCenter = true; atoml.IsReactiveCenter = true; atomR.IsReactiveCenter = true; reactant.GetBond(atomR, atoml).IsReactiveCenter = true;; } } } } } } }
public bool HasPerfectConfiguration(IAtom atom, IAtomContainer ac) { var bondOrderSum = ac.GetBondOrderSum(atom); var maxBondOrder = ac.GetMaximumBondOrder(atom); var atomTypes = structgenATF.GetAtomTypes(atom.Symbol); if (!atomTypes.Any()) { return(true); } Debug.WriteLine("*** Checking for perfect configuration ***"); try { Debug.WriteLine($"Checking configuration of atom {ac.Atoms.IndexOf(atom)}"); Debug.WriteLine($"Atom has bondOrderSum = {bondOrderSum}"); Debug.WriteLine($"Atom has max = {bondOrderSum}"); } catch (Exception) { } foreach (var atomType in atomTypes) { if (bondOrderSum == atomType.BondOrderSum && maxBondOrder == atomType.MaxBondOrder) { try { Debug.WriteLine($"Atom {ac.Atoms.IndexOf(atom)} has perfect configuration"); } catch (Exception) { } return(true); } } try { Debug.WriteLine($"*** Atom {ac.Atoms.IndexOf(atom)} has imperfect configuration ***"); } catch (Exception) { } return(false); }
/// <summary> /// Calculate the electronegativity of orbitals pi. /// </summary> /// <param name="ac"></param> /// <param name="atom">atom for which effective atom electronegativity should be calculated</param> /// <param name="maxIterations">The maximal number of Iteration</param> /// <param name="maxResonStruc">The maximal number of Resonance Structures</param> /// <returns>Electronegativity of orbitals pi.</returns> public double CalculatePiElectronegativity(IAtomContainer ac, IAtom atom, int maxIterations, int maxResonStruc) { MaxIterations = maxIterations; MaxResonanceStructures = maxResonStruc; double electronegativity = 0; try { if (!ac.Equals(acOldP)) { molPi = ac.Builder.NewAtomContainer(ac); peoe = new GasteigerMarsiliPartialCharges(); peoe.AssignGasteigerMarsiliSigmaPartialCharges(molPi, true); var iSet = ac.Builder.NewAtomContainerSet(); iSet.Add(molPi); iSet.Add(molPi); gasteigerFactors = pepe.AssignrPiMarsilliFactors(iSet); acOldP = ac; } IAtom atomi = molPi.Atoms[ac.Atoms.IndexOf(atom)]; int atomPosition = molPi.Atoms.IndexOf(atomi); int stepSize = pepe.StepSize; int start = (stepSize * (atomPosition) + atomPosition); double q = atomi.Charge.Value; if (molPi.GetConnectedLonePairs(molPi.Atoms[atomPosition]).Any() || molPi.GetMaximumBondOrder(atomi) != BondOrder.Single || atomi.FormalCharge != 0) { return((gasteigerFactors[1][start]) + (q * gasteigerFactors[1][start + 1]) + (gasteigerFactors[1][start + 2] * (q * q))); } } catch (Exception e) { Trace.TraceError(e.StackTrace); } return(electronegativity); }
/// <summary> /// Calculate the count of atoms of the largest pi system in the supplied <see cref="IAtomContainer"/>. /// </summary> /// <returns>the number of atoms in the largest pi system of this AtomContainer</returns> public Result Calculate(IAtomContainer container) { container = (IAtomContainer)container.Clone(); if (checkAromaticity) { AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(container); Aromaticity.CDKLegacy.Apply(container); } int largestPiSystemAtomsCount = 0; //Set all VisitedFlags to False for (int i = 0; i < container.Atoms.Count; i++) { container.Atoms[i].IsVisited = false; } for (int i = 0; i < container.Atoms.Count; i++) { //Possible pi System double bond or triple bond, charge, N or O (free electron pair) if ((container.GetMaximumBondOrder(container.Atoms[i]) != BondOrder.Single || Math.Abs(container.Atoms[i].FormalCharge.Value) >= 1 || container.Atoms[i].IsAromatic || container.Atoms[i].AtomicNumber.Equals(AtomicNumbers.N) || container.Atoms[i].AtomicNumber.Equals(AtomicNumbers.O)) && !container.Atoms[i].IsVisited) { var startSphere = new List <IAtom>(); var path = new List <IAtom>(); startSphere.Add(container.Atoms[i]); BreadthFirstSearch(container, startSphere, path); if (path.Count > largestPiSystemAtomsCount) { largestPiSystemAtomsCount = path.Count; } } } return(new Result(largestPiSystemAtomsCount)); }
/// <summary> /// Finds the AtomType matching the Atom's element symbol, formal charge and /// hybridization state. /// </summary> /// <param name="atomContainer">AtomContainer</param> /// <param name="atom">the target atom</param> /// <exception cref="CDKException">Exception thrown if something goes wrong</exception> /// <returns>the matching AtomType</returns> public IEnumerable <IAtomType> PossibleAtomTypes(IAtomContainer atomContainer, IAtom atom) { var bondOrderSum = atomContainer.GetBondOrderSum(atom); var maxBondOrder = atomContainer.GetMaximumBondOrder(atom); var charge = atom.FormalCharge.Value; var hcount = atom.ImplicitHydrogenCount.Value; var types = factory.GetAtomTypes(atom.Symbol); foreach (var type in types) { Debug.WriteLine(" ... matching atom ", atom, " vs ", type); if (bondOrderSum - charge + hcount <= type.BondOrderSum && !BondManipulator.IsHigherOrder(maxBondOrder, type.MaxBondOrder)) { yield return(type); } } Debug.WriteLine(" No Match"); yield break; }
/// <summary> /// Performs a breadthFirstSearch in an AtomContainer starting with a /// particular sphere, which usually consists of one start atom, and searches /// for a pi system. /// </summary> /// <param name="container">The AtomContainer to be searched</param> /// <param name="sphere">A sphere of atoms to start the search with</param> /// <param name="path">An array list which stores the atoms belonging to the pi system</param> /// <exception cref="CDKException"></exception> private void BreadthFirstSearch(IAtomContainer container, List <IAtom> sphere, List <IAtom> path) { IAtom nextAtom; var newSphere = new List <IAtom>(); foreach (var atom in sphere) { var bonds = container.GetConnectedBonds(atom); foreach (var bond in bonds) { nextAtom = ((IBond)bond).GetConnectedAtom(atom); if ((container.GetMaximumBondOrder(nextAtom) != BondOrder.Single || Math.Abs(nextAtom.FormalCharge.Value) >= 1 || nextAtom.IsAromatic || nextAtom.AtomicNumber.Equals(AtomicNumbers.N) || nextAtom.AtomicNumber.Equals(AtomicNumbers.O)) && !nextAtom.IsVisited) { //Debug.WriteLine("BDS> AtomNr:"+container.Atoms.IndexOf(nextAtom)+" maxBondOrder:"+container.GetMaximumBondOrder(nextAtom)+" Aromatic:"+nextAtom.IsAromatic+" FormalCharge:"+nextAtom.FormalCharge+" Charge:"+nextAtom.Charge+" Flag:"+nextAtom.IsVisited); path.Add(nextAtom); //Debug.WriteLine("BreadthFirstSearch is meeting new atom " + (nextAtomNr + 1)); nextAtom.IsVisited = true; if (container.GetConnectedBonds(nextAtom).Count() > 1) { newSphere.Add(nextAtom); } } else { nextAtom.IsVisited = true; } } } if (newSphere.Count > 0) { BreadthFirstSearch(container, newSphere, path); } }
/// <summary> /// Method which stores and assigns the factors a,b,c and CHI+. /// </summary> /// <param name="ac">AtomContainer</param> /// <returns>Array of doubles [a1,b1,c1,denom1,chi1,q1...an,bn,cn...] 1:Atom 1-n in AtomContainer</returns> public double[] AssignGasteigerSigmaMarsiliFactors(IAtomContainer ac) { //a,b,c,denom,chi,q var gasteigerFactors = new double[(ac.Atoms.Count * (StepSize + 1))]; var factors = new double[] { 0.0, 0.0, 0.0 }; for (int i = 0; i < ac.Atoms.Count; i++) { factors[0] = 0.0; factors[1] = 0.0; factors[2] = 0.0; var atom = ac.Atoms[i]; var symbol = atom.Symbol; var maxBondOrder = ac.GetMaximumBondOrder(atom); var charge = atom.FormalCharge; switch (atom.AtomicNumber) { case AtomicNumbers.H: factors[0] = 7.17; factors[1] = 6.24; factors[2] = -0.56; break; case AtomicNumbers.C: if (maxBondOrder == BondOrder.Double || (maxBondOrder == BondOrder.Single && (charge == -1 || charge == +1))) { factors[0] = 8.79; /* 8.79 *//* 8.81 */ factors[1] = 9.32; /* 9.32 *//* 9.34 */ factors[2] = 1.51; /* 1.51 *//* 1.52 */ } else if (maxBondOrder == BondOrder.Single && charge == 0) { factors[0] = 7.98; factors[1] = 9.18; factors[2] = 1.88; } else if (maxBondOrder == BondOrder.Triple || maxBondOrder == BondOrder.Quadruple) { factors[0] = 10.39; /* 10.39 */ factors[1] = 9.45; /* 9.45 */ factors[2] = 0.73; } break; case AtomicNumbers.N: if ((maxBondOrder == BondOrder.Single) && (charge != -1)) { factors[0] = 11.54; factors[1] = 10.82; factors[2] = 1.36; } else if ((maxBondOrder == BondOrder.Double) || (maxBondOrder == BondOrder.Single)) { factors[0] = 12.87; factors[1] = 11.15; factors[2] = 0.85; } else if (maxBondOrder == BondOrder.Triple || maxBondOrder == BondOrder.Quadruple) { factors[0] = 17.68; /* 15.68 */ factors[1] = 12.70; /* 11.70 */ factors[2] = -0.27; /*-0.27*/ } break; case AtomicNumbers.O: if ((maxBondOrder == BondOrder.Single) && (charge != -1)) { factors[0] = 14.18; factors[1] = 12.92; factors[2] = 1.39; } else if ((maxBondOrder == BondOrder.Double) || (maxBondOrder == BondOrder.Single)) { factors[0] = 17.07; /* paramaters aren'T correct parametrized. */ factors[1] = 13.79; factors[2] = 0.47; /* 0.47 */ } break; case AtomicNumbers.Si: // <--not correct factors[0] = 8.10; // <--not correct factors[1] = 7.92; // <--not correct factors[2] = 1.78; // <--not correct break; case AtomicNumbers.P: factors[0] = 8.90; factors[1] = 8.32; factors[2] = 1.58; break; case AtomicNumbers.S: factors[0] = 10.14; /* 10.14 */ factors[1] = 9.13; /* 9.13 */ factors[2] = 1.38; /* 1.38 */ break; case AtomicNumbers.F: factors[0] = 14.66; factors[1] = 13.85; factors[2] = 2.31; break; case AtomicNumbers.Cl: factors[0] = 12.31; /* 11.0 *//* 12.31 */ factors[1] = 10.84; /* 9.69 *//* 10.84 */ factors[2] = 1.512; /* 1.35 *//* 1.512 */ break; case AtomicNumbers.Br: factors[0] = 11.44; /* 10.08 *//* 11.2 */ factors[1] = 9.63; /* 8.47 *//* 9.4 */ factors[2] = 1.31; /* 1.16 *//* 1.29 */ break; case AtomicNumbers.I: factors[0] = 9.88; /* 9.90 */ factors[1] = 7.95; /* 7.96 */ factors[2] = 0.945; /* 0.96 */ break; default: throw new CDKException($"Partial charge not-supported for element: '{symbol}'."); } gasteigerFactors[StepSize * i + i] = factors[0]; gasteigerFactors[StepSize * i + i + 1] = factors[1]; gasteigerFactors[StepSize * i + i + 2] = factors[2]; gasteigerFactors[StepSize * i + i + 5] = atom.Charge.Value; if (factors[0] == 0 && factors[1] == 0 && factors[2] == 0) { gasteigerFactors[StepSize * i + i + 3] = 1; } else { gasteigerFactors[StepSize * i + i + 3] = factors[0] + factors[1] + factors[2]; } } return(gasteigerFactors); }
/// <summary> /// The method calculates the number of rotatable bonds of an atom container. /// If the boolean parameter is set to <see langword="true"/>, terminal bonds are included. /// </summary> /// <returns>number of rotatable bonds</returns> /// <param name="includeTerminals"><see langword="true"/> if terminal bonds are included</param> /// <param name="excludeAmides"><see langword="true"/> if amide C-N bonds should be excluded</param> public Result Calculate(IAtomContainer container, bool includeTerminals = false, bool excludeAmides = false) { container = (IAtomContainer)container.Clone(); IRingSet ringSet; try { ringSet = new SpanningTree(container).GetBasicRings(); } catch (NoSuchAtomException) { return(new Result(0)); } foreach (var bond in container.Bonds) { if (ringSet.GetRings(bond).Count() > 0) { bond.IsInRing = true; } } int rotatableBondsCount = 0; foreach (var bond in container.Bonds) { var atom0 = bond.Atoms[0]; var atom1 = bond.Atoms[1]; if (atom0.AtomicNumber.Equals(AtomicNumbers.H) || atom1.AtomicNumber.Equals(AtomicNumbers.H)) { continue; } if (bond.Order == BondOrder.Single) { if (BondManipulator.IsLowerOrder(container.GetMaximumBondOrder(atom0), BondOrder.Triple) && BondManipulator.IsLowerOrder(container.GetMaximumBondOrder(atom1), BondOrder.Triple)) { if (!bond.IsInRing) { if (excludeAmides && (IsAmide(atom0, atom1, container) || IsAmide(atom1, atom0, container))) { continue; } // if there are explicit H's we should ignore those bonds var degree0 = container.GetConnectedBonds(atom0).Count() - GetConnectedHCount(container, atom0); var degree1 = container.GetConnectedBonds(atom1).Count() - GetConnectedHCount(container, atom1); if ((degree0 == 1) || (degree1 == 1)) { if (includeTerminals) { rotatableBondsCount += 1; } } else { rotatableBondsCount += 1; } } } } } return(new Result(rotatableBondsCount)); }
/// <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); }
public int CalculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container) { return(this.CalculateNumberOfImplicitHydrogens(atom, container.GetBondOrderSum(atom), container.GetMaximumBondOrder(atom), container.GetConnectedBonds(atom).Count())); }
// this method returns the partial charge increment for a given atom /// <summary> /// Gets the atomicChargeIncrement attribute of the InductivePartialCharges object. /// </summary> /// <param name="ac">AtomContainer</param> /// <param name="atomPosition">position of target atom</param> /// <param name="ElEn">electronegativity of target atom</param> /// <param name="step">step in iteration</param> /// <returns>The atomic charge increment for the target atom</returns> /// <exception cref="CDKException"></exception> private double GetAtomicChargeIncrement(IAtomContainer ac, int atomPosition, double[] ElEn, int step) { IAtom[] allAtoms = null; IAtom target = null; double incrementedCharge = 0; double radiusTarget = 0; target = ac.Atoms[atomPosition]; allAtoms = ac.Atoms.ToArray(); double tmp = 0; double radius = 0; IAtomType type = null; try { type = factory.GetAtomType(target.Symbol); if (GetCovalentRadius(target.AtomicNumber, ac.GetMaximumBondOrder(target)) > 0) { radiusTarget = GetCovalentRadius(target.AtomicNumber, 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); } for (int a = 0; a < allAtoms.Length; a++) { if (!target.Equals(allAtoms[a])) { tmp = 0; var atom = allAtoms[a]; 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(allAtoms[a])) > 0) { radius = GetCovalentRadius(atom.AtomicNumber, ac.GetMaximumBondOrder(allAtoms[a])); } else { radius = type.CovalentRadius.Value; } tmp = (ElEn[a + ((step - 1) * allAtoms.Length)] - ElEn[atomPosition + ((step - 1) * allAtoms.Length)]); tmp = tmp * ((radius * radius) + (radiusTarget * radiusTarget)); tmp = tmp / (CalculateSquaredDistanceBetweenTwoAtoms(target, allAtoms[a])); incrementedCharge += tmp; } } incrementedCharge = 0.172 * incrementedCharge; return(incrementedCharge); }
/// <summary> /// Sets a branch atom to a ring or aliphatic chain. /// </summary> /// <param name="unplacedAtom">The new branchAtom</param> /// <param name="atomA">placed atom to which the unplaced atom is connected</param> /// <param name="atomNeighbours">placed atomNeighbours of atomA</param> private static void SetBranchAtom(IAtomContainer molecule, IAtom unplacedAtom, IAtom atomA, IAtomContainer atomNeighbours, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d) { //Debug.WriteLine("****** SET Branch Atom ****** >"+molecule.Atoms.IndexOf(unplacedAtom)); IAtomContainer noCoords = molecule.Builder.NewAtomContainer(); noCoords.Atoms.Add(unplacedAtom); Vector3 centerPlacedMolecule = ap3d.GeometricCenterAllPlacedAtoms(molecule); IAtom atomB = atomNeighbours.Atoms[0]; string atypeNameA = atomA.AtomTypeName; string atypeNameB = atomB.AtomTypeName; string atypeNameUnplaced = unplacedAtom.AtomTypeName; double length = ap3d.GetBondLengthValue(atypeNameA, atypeNameUnplaced); double angle = (ap3d.GetAngleValue(atypeNameB, atypeNameA, atypeNameUnplaced)) * Math.PI / 180; // Console.Out.WriteLine("A:"+atomA.Symbol+" "+atomA.AtomTypeName+ // " B:"+atomB.Symbol+" "+atomB.AtomTypeName // +" unplaced Atom:" // +unplacedAtom.AtomTypeName+" BL:"+length+" Angle:"+angle // +" FormalNeighbour:" // +atomA.FormalNeighbourCount+" HYB:"+atomA.getFlag // (CDKConstants.HYBRIDIZATION_SP2) // +" #Neigbhours:"+atomNeighbours.Atoms.Count); IAtom atomC = ap3d.GetPlacedHeavyAtom(molecule, atomB, atomA); Vector3[] branchPoints = atlp3d.Get3DCoordinatesForLigands(atomA, noCoords, atomNeighbours, atomC, (atomA.FormalNeighbourCount.Value - atomNeighbours.Atoms.Count), length, angle); double distance = 0; int farthestPoint = 0; for (int i = 0; i < branchPoints.Length; i++) { if (Math.Abs(Vector3.Distance(branchPoints[i], centerPlacedMolecule)) > Math.Abs(distance)) { distance = Vector3.Distance(branchPoints[i], centerPlacedMolecule); farthestPoint = i; } } int stereo = -1; IBond unplacedBond = molecule.GetBond(atomA, unplacedAtom); if (atomA.StereoParity != 0 || (unplacedBond.Stereo == BondStereo.Up || unplacedBond.Stereo == BondStereo.Down) && molecule.GetMaximumBondOrder(atomA) == BondOrder.Single) { if (atomNeighbours.Atoms.Count > 1) { stereo = AtomTetrahedralLigandPlacer3D.MakeStereocenter(atomA.Point3D.Value, molecule.GetBond(atomA, unplacedAtom), (atomNeighbours.Atoms[0]).Point3D.Value, (atomNeighbours.Atoms[1]).Point3D.Value, branchPoints); } } if (stereo != -1) { farthestPoint = stereo; } unplacedAtom.Point3D = branchPoints[farthestPoint]; unplacedAtom.IsPlaced = true; }
/// <summary> /// Method which assigns the polarizabilitiyFactors. /// </summary> /// <param name="atomContainer">AtomContainer</param> /// <param name="atom">Atom</param> /// <returns>double polarizabilitiyFactor</returns> private static double GetKJPolarizabilityFactor(IAtomContainer atomContainer, IAtom atom) { double polarizabilitiyFactor = 0; switch (atom.AtomicNumber) { case AtomicNumbers.H: polarizabilitiyFactor = 0.387; break; case AtomicNumbers.C: if (atom.IsAromatic) { polarizabilitiyFactor = 1.230; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Single) { polarizabilitiyFactor = 1.064; /* 1.064 */ } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Double) { if (GetNumberOfHydrogen(atomContainer, atom) == 0) { polarizabilitiyFactor = 1.382; } else { polarizabilitiyFactor = 1.37; } } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Triple || atomContainer.GetMaximumBondOrder(atom) == BondOrder.Quadruple) { polarizabilitiyFactor = 1.279; } break; case AtomicNumbers.N: if (atom.Charge != null && atom.Charge < 0) { polarizabilitiyFactor = 1.090; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Single) { polarizabilitiyFactor = 1.094; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Double) { polarizabilitiyFactor = 1.030; } else { polarizabilitiyFactor = 0.852; } break; case AtomicNumbers.O: if (atom.Charge != null && atom.Charge == -1) { polarizabilitiyFactor = 1.791; } else if (atom.Charge != null && atom.Charge == 1) { polarizabilitiyFactor = 0.422; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Single) { polarizabilitiyFactor = 0.664; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Double) { polarizabilitiyFactor = 0.460; } break; case AtomicNumbers.P: if (atomContainer.GetConnectedBonds(atom).Count() == 4 && atomContainer.GetMaximumBondOrder(atom) == BondOrder.Double) { polarizabilitiyFactor = 0; } break; case AtomicNumbers.S: if (atom.IsAromatic) { polarizabilitiyFactor = 3.38; } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Single) { polarizabilitiyFactor = 3.20; /* 3.19 */ } else if (atomContainer.GetMaximumBondOrder(atom) == BondOrder.Double) { if (GetNumberOfHydrogen(atomContainer, atom) == 0) { polarizabilitiyFactor = 3.51; } else { polarizabilitiyFactor = 3.50; } } else { polarizabilitiyFactor = 3.42; } break; case AtomicNumbers.F: polarizabilitiyFactor = 0.296; break; case AtomicNumbers.Cl: polarizabilitiyFactor = 2.343; break; case AtomicNumbers.Br: polarizabilitiyFactor = 3.5; break; case AtomicNumbers.I: polarizabilitiyFactor = 5.79; break; } return(polarizabilitiyFactor); }
/// <summary> /// Gets the paulingElectronegativities attribute of the /// InductivePartialCharges object. /// </summary> /// <param name="ac">AtomContainer</param> /// <param name="modified">if true, some values are modified by following the reference</param> /// <returns>The pauling electronegativities</returns> public double[] GetPaulingElectronegativities(IAtomContainer ac, bool modified) { var paulingElectronegativities = new double[ac.Atoms.Count]; string symbol = null; int atomicNumber = 0; try { ifac = CDK.IsotopeFactory; for (int i = 0; i < ac.Atoms.Count; i++) { var atom = ac.Atoms[i]; symbol = ac.Atoms[i].Symbol; var element = ifac.GetElement(symbol); atomicNumber = element.AtomicNumber; if (modified) { switch (atom.AtomicNumber) { case AtomicNumbers.Cl: paulingElectronegativities[i] = 3.28; break; case AtomicNumbers.Br: paulingElectronegativities[i] = 3.13; break; case AtomicNumbers.I: paulingElectronegativities[i] = 2.93; break; case AtomicNumbers.H: paulingElectronegativities[i] = 2.10; break; case AtomicNumbers.C: if (ac.GetMaximumBondOrder(atom) == BondOrder.Single) { // Csp3 paulingElectronegativities[i] = 2.20; } else if (ac.GetMaximumBondOrder(atom) == BondOrder.Double) { paulingElectronegativities[i] = 2.31; } else { paulingElectronegativities[i] = 3.15; } break; case AtomicNumbers.O: if (ac.GetMaximumBondOrder(atom) == BondOrder.Single) { // Osp3 paulingElectronegativities[i] = 3.20; } else if (ac.GetMaximumBondOrder(atom) != BondOrder.Single) { paulingElectronegativities[i] = 4.34; } break; case AtomicNumbers.Si: paulingElectronegativities[i] = 1.99; break; case AtomicNumbers.S: paulingElectronegativities[i] = 2.74; break; case AtomicNumbers.N: paulingElectronegativities[i] = 2.59; break; default: paulingElectronegativities[i] = pauling[atomicNumber]; break; } } else { paulingElectronegativities[i] = pauling[atomicNumber]; } } return(paulingElectronegativities); } catch (Exception ex1) { Debug.WriteLine(ex1); throw new CDKException($"Problems with IsotopeFactory due to {ex1.Message}", ex1); } }
/// <summary> /// Method which stores and assigns the factors a,b,c and CHI+. /// </summary> /// <param name="setAc"></param> /// <returns>Array of doubles [a1,b1,c1,denom1,chi1,q1...an,bn,cn...] 1:Atom 1-n in AtomContainer</returns> public double[][] AssignrPiMarsilliFactors(IChemObjectSet <IAtomContainer> setAc) { //a,b,c,denom,chi,q double[][] gasteigerFactors = Arrays.CreateJagged <double>(setAc.Count, (setAc[0].Atoms.Count * (StepSize + 1))); double[] factors = new double[] { 0.0, 0.0, 0.0 }; for (int k = 1; k < setAc.Count; k++) { IAtomContainer ac = setAc[k]; for (int i = 0; i < ac.Atoms.Count; i++) { factors[0] = 0.0; factors[1] = 0.0; factors[2] = 0.0; switch (ac.Atoms[i].AtomicNumber) { case AtomicNumbers.H: factors[0] = 0.0; factors[1] = 0.0; factors[2] = 0.0; break; case AtomicNumbers.C: factors[0] = 5.98; /* 5.98-5.60 */ factors[1] = 7.93; /* 7.93-8.93 */ factors[2] = 1.94; break; case AtomicNumbers.O: if (ac.GetMaximumBondOrder(ac.Atoms[i]) != BondOrder.Single) { factors[0] = 11.2; /* 11.2-10.0 */ factors[1] = 13.24; /* 13.24-13.86 */ factors[2] = 9.68; } else { factors[0] = 7.91; factors[1] = 14.76; factors[2] = 6.85; } break; case AtomicNumbers.N: if (ac.GetMaximumBondOrder(ac.Atoms[i]) != BondOrder.Single) { factors[0] = 8.95; /* 7.95 */ factors[1] = 9.73; /* 9.73 */ factors[2] = 2.67; /* 2.67 */ } else { factors[0] = 4.54; factors[1] = 11.86; factors[2] = 7.32; } break; case AtomicNumbers.P: { // <--No correct if (ac.GetMaximumBondOrder(ac.Atoms[i]) != BondOrder.Single) { factors[0] = 10.73; // <--No correct factors[1] = 11.16; // <--No correct factors[2] = 6.81; // <--No correct } else { factors[0] = 9.60; // <--No correct factors[1] = 13.32; // <--No correct factors[2] = 2.72; // <--No correct } } break; case AtomicNumbers.S: if (ac.GetMaximumBondOrder(ac.Atoms[i]) != BondOrder.Single) { factors[0] = 7.73; factors[1] = 8.16; factors[2] = 1.81; } else { factors[0] = 6.60; factors[1] = 10.32; factors[2] = 3.72; } break; case AtomicNumbers.F: factors[0] = 7.14 /* 7.34 */; factors[1] = 13.86; factors[2] = 5.68; break; case AtomicNumbers.Cl: factors[0] = 6.51; /* 6.50 */ factors[1] = 11.02; factors[2] = 4.52; break; case AtomicNumbers.Br: factors[0] = 5.20; factors[1] = 9.68; factors[2] = 4.48; break; case AtomicNumbers.I: factors[0] = 4.95; factors[1] = 8.81; factors[2] = 3.86; break; } gasteigerFactors[k][StepSize * i + i] = factors[0]; gasteigerFactors[k][StepSize * i + i + 1] = factors[1]; gasteigerFactors[k][StepSize * i + i + 2] = factors[2]; gasteigerFactors[k][StepSize * i + i + 5] = ac.Atoms[i].Charge.Value; if (factors[0] == 0 && factors[1] == 0 && factors[2] == 0) { gasteigerFactors[k][StepSize * i + i + 3] = 1; } else { gasteigerFactors[k][StepSize * i + i + 3] = factors[0] + factors[1] + factors[2]; } } } return(gasteigerFactors); }
/// <summary> /// Method assigns atom types to atoms (calculates sssr and aromaticity) /// </summary> /// <returns>sssrf set</returns> /// <exception cref="CDKException"> Problems detecting aromaticity or making hose codes.</exception> public IRingSet AssignAtomTyps(IAtomContainer molecule) { IAtom atom = null; string hoseCode = ""; HOSECodeGenerator hcg = new HOSECodeGenerator(); int NumberOfRingAtoms = 0; IRingSet ringSetMolecule = Cycles.FindSSSR(molecule).ToRingSet(); bool isInHeteroRing = false; try { AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(molecule); Aromaticity.CDKLegacy.Apply(molecule); } catch (Exception cdk1) { throw new CDKException("AROMATICITYError: Cannot determine aromaticity due to: " + cdk1.Message, cdk1); } for (int i = 0; i < molecule.Atoms.Count; i++) { atom = molecule.Atoms[i]; if (ringSetMolecule.Contains(atom)) { NumberOfRingAtoms = NumberOfRingAtoms + 1; atom.IsInRing = true; atom.IsAliphatic = false; var ringSetA = ringSetMolecule.GetRings(atom).ToList(); RingSetManipulator.Sort(ringSetA); IRing sring = (IRing)ringSetA[ringSetA.Count - 1]; atom.SetProperty("RING_SIZE", sring.RingSize); foreach (var ring in ringSetA) { if (IsHeteroRingSystem(ring)) { break; } } } else { atom.IsAliphatic = true; atom.IsInRing = false; isInHeteroRing = false; } atom.SetProperty("MAX_BOND_ORDER", molecule.GetMaximumBondOrder(atom).Numeric()); try { hoseCode = hcg.GetHOSECode(molecule, atom, 3); //Debug.WriteLine("HOSECODE GENERATION: ATOM "+i+" HoseCode: "+hoseCode+" "); } catch (CDKException ex1) { Console.Out.WriteLine("Could not build HOSECode from atom " + i + " due to " + ex1.ToString()); throw new CDKException("Could not build HOSECode from atom " + i + " due to " + ex1.ToString(), ex1); } try { ConfigureAtom(atom, hoseCode, isInHeteroRing); } catch (CDKException ex2) { Console.Out.WriteLine("Could not final configure atom " + i + " due to " + ex2.ToString()); throw new CDKException("Could not final configure atom due to problems with force field", ex2); } } // IBond[] bond = molecule.Bonds; string bondType; foreach (var bond in molecule.Bonds) { //Debug.WriteLine("bond[" + i + "] properties : " + molecule.Bonds[i].GetProperties()); bondType = "0"; if (bond.Order == BondOrder.Single) { if ((bond.Begin.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) && ((bond.End.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) || (bond.End.AtomTypeName.Equals("C=", StringComparison.Ordinal)))) { bondType = "1"; } if ((bond.Begin.AtomTypeName.Equals("C=", StringComparison.Ordinal)) && ((bond.End.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) || (bond.End.AtomTypeName.Equals("C=", StringComparison.Ordinal)))) { bondType = "1"; } if ((bond.Begin.AtomTypeName.Equals("Csp", StringComparison.Ordinal)) && (bond.End.AtomTypeName.Equals("Csp", StringComparison.Ordinal))) { bondType = "1"; } } // molecule.Bonds[i].SetProperty("MMFF94 bond type", bondType); bond.SetProperty("MMFF94 bond type", bondType); //Debug.WriteLine("bond[" + i + "] properties : " + molecule.Bonds[i].GetProperties()); } return(ringSetMolecule); }
internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, int length, bool checkPrev, AtomCheck atomCheck) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(reactant); Aromaticity.CDKLegacy.Apply(reactant); AllRingsFinder arf = new AllRingsFinder(); IRingSet ringSet = arf.FindAllRings(reactant); for (int ir = 0; ir < ringSet.Count; ir++) { IRing ring = (IRing)ringSet[ir]; for (int jr = 0; jr < ring.Atoms.Count; jr++) { IAtom aring = ring.Atoms[jr]; aring.IsInRing = true; } } // if the parameter hasActiveCenter is not fixed yet, set the active centers IParameterReaction ipr = base.GetParameterClass(typeof(SetReactionCenter)); if (ipr != null && !ipr.IsSetParameter) { SetActiveCenters(reactant, length, checkPrev, atomCheck); } HOSECodeGenerator hcg = new HOSECodeGenerator(); foreach (var atomi in reactant.Atoms) { if (atomi.IsReactiveCenter && reactant.GetConnectedSingleElectrons(atomi).Count() == 1) { IEnumerable <IAtom> atom1s = null; if (checkPrev) { hcg.GetSpheres(reactant, atomi, length - 1, true); atom1s = hcg.GetNodesInSphere(length - 1); } hcg.GetSpheres(reactant, atomi, length, true); foreach (var atoml in hcg.GetNodesInSphere(length)) { if (atoml != null && atoml.IsReactiveCenter && !atoml.IsInRing && (atoml.FormalCharge ?? 0) == 0 && !atoml.AtomicNumber.Equals(AtomicNumbers.H) && reactant.GetMaximumBondOrder(atoml) == BondOrder.Single) { foreach (var atomR in reactant.GetConnectedAtoms(atoml)) { if (atom1s != null && atom1s.Contains(atomR)) { continue; } if (reactant.GetBond(atomR, atoml).IsReactiveCenter && atomR.IsReactiveCenter && atomCheck(atomR)) { var atomList = new List <IAtom> { atomR, atomi, atoml }; var bondList = new List <IBond> { reactant.GetBond(atomR, atoml) }; var moleculeSet = reactant.Builder.NewChemObjectSet <IAtomContainer>(); moleculeSet.Add(reactant); var reaction = Mechanism.Initiate(moleculeSet, atomList, bondList); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } } } } } return(setOfReactions); }
/// <summary> /// Check an Atom whether it may be conjugated or not. /// </summary> /// <param name="ac">The AtomContainer containing currentAtom</param> /// <param name="currentAtom">The Atom to check</param> /// <returns>-1 if isolated, 0 if conjugated, 1 if cumulative db</returns> private static int CheckAtom(IAtomContainer ac, IAtom currentAtom) { int check = -1; var atoms = ac.GetConnectedAtoms(currentAtom).ToReadOnlyList(); var bonds = ac.GetConnectedBonds(currentAtom).ToReadOnlyList(); if (currentAtom.IsAromatic) { check = 0; } else if (currentAtom.FormalCharge == 1) /* && currentAtom.Symbol.Equals("C") */ { check = 0; } else if (currentAtom.FormalCharge == -1) { //// NEGATIVE CHARGES WITH A NEIGHBOOR PI BOND //// int counterOfPi = 0; foreach (var atom in atoms) { if (ac.GetMaximumBondOrder(atom) != BondOrder.Single) { counterOfPi++; } } if (counterOfPi > 0) { check = 0; } } else { int se = ac.GetConnectedSingleElectrons(currentAtom).Count(); if (se == 1) { check = 0; //// DETECTION of radicals } else if (ac.GetConnectedLonePairs(currentAtom).Any() /* && (currentAtom.Symbol.Equals("N") */) { check = 0; //// DETECTION of lone pair } else { int highOrderBondCount = 0; for (int j = 0; j < atoms.Count; j++) { var bond = bonds[j]; if (bond == null || bond.Order != BondOrder.Single) { highOrderBondCount++; } else { } } if (highOrderBondCount == 1) { check = 0; } else if (highOrderBondCount > 1) { check = 1; } } } return(check); }