/// <summary> /// It is needed to call the addExplicitHydrogensToSatisfyValency method from /// the class tools.HydrogenAdder, and 3D coordinates. /// </summary> /// <param name="atom">The <see cref="IAtom"/> for which the <see cref="Result"/> is requested</param> /// <returns>a double with polarizability of the heavy atom</returns> public Result Calculate(IAtom atom) { var symbol = atom.Symbol; var type = this.AtomTypeFactory.GetAtomType(symbol); var radiusTarget = type.CovalentRadius.Value; double atomicHardness = 0; foreach (var curAtom in container.Atoms) { if (atom.Point3D == null || curAtom.Point3D == null) { throw new CDKException("The target atom or current atom had no 3D coordinates. These are required"); } if (!atom.Equals(curAtom)) { double partial = 0; symbol = curAtom.Symbol; type = this.AtomTypeFactory.GetAtomType(symbol); var radius = type.CovalentRadius.Value; partial += radius * radius; partial += (radiusTarget * radiusTarget); partial = partial / CalculateSquareDistanceBetweenTwoAtoms(atom, curAtom); atomicHardness += partial; } } atomicHardness = 2 * atomicHardness; atomicHardness = atomicHardness * 0.172; atomicHardness = 1 / atomicHardness; return(new Result(atomicHardness)); }
/// <summary> /// /// Returns bond map between source and target molecules based on the atoms /// <param name="ac1">source molecule</param> /// <param name="ac2">target molecule</param> /// <param name="mapping">mappings between source and target molecule atoms</param> /// <returns>bond map between source and target molecules based on the atoms</returns> /// </summary> public static IReadOnlyDictionary <IBond, IBond> MakeBondMapOfAtomMap( IAtomContainer ac1, IAtomContainer ac2, IReadOnlyDictionary <IAtom, IAtom> mapping) { var maps = new Dictionary <IBond, IBond>(); foreach (var mapS in mapping) { IAtom indexI = mapS.Key; IAtom indexJ = mapS.Value; foreach (var mapD in mapping) { IAtom indexIPlus = mapD.Key; IAtom indexJPlus = mapD.Value; if (!indexI.Equals(indexIPlus) && !indexJ.Equals(indexJPlus)) { IBond ac1Bond = ac1.GetBond(indexI, indexIPlus); if (ac1Bond != null) { IBond ac2Bond = ac2.GetBond(indexJ, indexJPlus); if (ac2Bond != null) { maps[ac1Bond] = ac2Bond; } } } } } return(maps); }
/// <summary> Get a list of all the paths between two atoms. /// <p/> /// If the two atoms are the same an empty list is returned. Note that this problem /// is NP-hard and so can take a long time for large graphs. /// /// </summary> /// <param name="atomContainer">The molecule to consider /// </param> /// <param name="start"> The starting Atom of the path /// </param> /// <param name="end"> The ending Atom of the path /// </param> /// <returns> A <code>List</code> containing all the paths between the specified atoms /// </returns> public static System.Collections.IList getAllPaths(IAtomContainer atomContainer, IAtom start, IAtom end) { allPaths = new System.Collections.ArrayList(); if (start.Equals(end)) { return(allPaths); } findPathBetween(atomContainer, start, end, new System.Collections.ArrayList()); return(allPaths); }
/// <summary> /// Helper method, used to help construct a configuration. /// </summary> /// <param name="atom"></param> /// <param name="container"></param> /// <returns>the array position of atom in container</returns> private static int GetAtomPosition(IAtom atom, IAtomContainer container) { for (int i = 0; i < container.Atoms.Count; i++) { if (atom.Equals(container.Atoms[i])) { return(i); } } return(-1); }
/// <summary> /// Get a list of all the paths between two atoms. /// <para> /// If the two atoms are the same an empty list is returned. Note that this problem /// is NP-hard and so can take a long time for large graphs.</para> /// </summary> /// <param name="atomContainer">The molecule to consider</param> /// <param name="start">The starting Atom of the path</param> /// <param name="end">The ending Atom of the path</param> /// <returns>A <see cref="IList{T}"/> containing all the paths between the specified atoms</returns> public static IList <IList <IAtom> > GetAllPaths(IAtomContainer atomContainer, IAtom start, IAtom end) { var allPaths = new List <IList <IAtom> >(); if (start.Equals(end)) { return(allPaths); } FindPathBetween(allPaths, atomContainer, start, end, new List <IAtom>()); return(allPaths); }
public static bool replaceAtomByAtom(IAtomContainer container, IAtom atom, IAtom newAtom) { if (!container.contains(atom)) { // it should complain return(false); } else { container.setAtomAt(container.getAtomNumber(atom), newAtom); IElectronContainer[] electronContainers = container.ElectronContainers; for (int i = 0; i < electronContainers.Length; i++) { if (electronContainers[i] is IBond) { IBond bond = (IBond)electronContainers[i]; if (bond.contains(atom)) { for (int j = 0; j < bond.AtomCount; j++) { if (atom.Equals(bond.getAtomAt(j))) { bond.setAtomAt(newAtom, j); } } } } else if (electronContainers[i] is ILonePair) { ILonePair lonePair = (ILonePair)electronContainers[i]; if (atom.Equals(lonePair.Atom)) { lonePair.Atom = newAtom; } } } return(true); } }
/// <summary> /// Gets the first placed Heavy Atom around atomA which is not atomB. /// </summary> /// <param name="molecule"></param> /// <param name="atomA">Description of the Parameter</param> /// <param name="atomB">Description of the Parameter</param> /// <returns>The placedHeavyAtom value</returns> public IAtom GetPlacedHeavyAtom(IAtomContainer molecule, IAtom atomA, IAtom atomB) { var bonds = molecule.GetConnectedBonds(atomA); foreach (var bond in bonds) { IAtom connectedAtom = bond.GetOther(atomA); if (IsPlacedHeavyAtom(connectedAtom) && !connectedAtom.Equals(atomB)) { return(connectedAtom); } } return(null); }
public override bool IsStereoMisMatch() { bool flag = false; IAtomContainer reactant = ReactantMolecule; IAtomContainer product = ProductMolecule; int score = 0; foreach (var mappingI in firstAtomMCS) { IAtom indexI = mappingI.Key; IAtom indexJ = mappingI.Value; foreach (var mappingJ in firstAtomMCS) { IAtom indexIPlus = mappingJ.Key; IAtom indexJPlus = mappingJ.Value; if (!indexI.Equals(indexIPlus) && !indexJ.Equals(indexJPlus)) { IAtom sourceAtom1 = indexI; IAtom sourceAtom2 = indexIPlus; IBond rBond = reactant.GetBond(sourceAtom1, sourceAtom2); IAtom targetAtom1 = indexJ; IAtom targetAtom2 = indexJPlus; IBond pBond = product.GetBond(targetAtom1, targetAtom2); if ((rBond != null && pBond != null) && (rBond.Stereo != pBond.Stereo)) { score++; } } } } if (score > 0) { flag = true; } return(flag); }
/// <summary> /// The actual writing of the output. /// </summary> /// <param name="obj"></param> /// <exception cref="CDKException">could not write RGroup query</exception> public override void Write(IChemObject obj) { if (!(obj is IRGroupQuery)) { throw new CDKException("Only IRGroupQuery input is accepted."); } try { IRGroupQuery rGroupQuery = (IRGroupQuery)obj; string now = DateTime.UtcNow.ToString("MMddyyHHmm", DateTimeFormatInfo.InvariantInfo); IAtomContainer rootAtc = rGroupQuery.RootStructure; //Construct header var rootBlock = new StringBuilder(); string header = "$MDL REV 1 " + now + LSEP + "$MOL" + LSEP + "$HDR" + LSEP + " Rgroup query file (RGFile)" + LSEP + " CDK " + now + "2D" + LSEP + LSEP + "$END HDR" + LSEP + "$CTAB"; rootBlock.Append(header).Append(LSEP); //Construct the root structure, the scaffold string rootCTAB = GetCTAB(rootAtc); rootCTAB = rootCTAB.Replace(LSEP + "M END" + LSEP, ""); rootBlock.Append(rootCTAB).Append(LSEP); //Write the root's LOG lines foreach (var rgrpNum in rGroupQuery.RGroupDefinitions.Keys) { RGroupList rgList = rGroupQuery.RGroupDefinitions[rgrpNum]; int restH = rgList.IsRestH ? 1 : 0; string logLine = "M LOG" + MDLV2000Writer.FormatMDLInt(1, 3) + MDLV2000Writer.FormatMDLInt(rgrpNum, 4) + MDLV2000Writer.FormatMDLInt(rgList.RequiredRGroupNumber, 4) + MDLV2000Writer.FormatMDLInt(restH, 4) + " " + rgList.Occurrence; rootBlock.Append(logLine).Append(LSEP); } //AAL lines are optional, they are needed for R-atoms with multiple bonds to the root //for which the order of the attachment points can not be implicitly derived //from the order in the atom block. See CT spec for more on that. foreach (var rgroupAtom in rGroupQuery.RootAttachmentPoints.Keys) { var rApo = rGroupQuery.RootAttachmentPoints[rgroupAtom]; if (rApo.Count > 1) { int prevPos = -1; int apoIdx = 1; bool implicitlyOrdered = true; while (rApo.ContainsKey(apoIdx) && implicitlyOrdered) { IAtom partner = rApo[apoIdx].GetOther(rgroupAtom); for (int atIdx = 0; atIdx < rootAtc.Atoms.Count; atIdx++) { if (rootAtc.Atoms[atIdx].Equals(partner)) { if (atIdx < prevPos) { implicitlyOrdered = false; } prevPos = atIdx; break; } } apoIdx++; } if (!implicitlyOrdered) { StringBuilder aalLine = new StringBuilder("M AAL"); for (int atIdx = 0; atIdx < rootAtc.Atoms.Count; atIdx++) { if (rootAtc.Atoms[atIdx].Equals(rgroupAtom)) { aalLine.Append(MDLV2000Writer.FormatMDLInt((atIdx + 1), 4)); aalLine.Append(MDLV2000Writer.FormatMDLInt(rApo.Count, 3)); apoIdx = 1; while (rApo.ContainsKey(apoIdx)) { IAtom partner = rApo[apoIdx].GetOther(rgroupAtom); for (int a = 0; a < rootAtc.Atoms.Count; a++) { if (rootAtc.Atoms[a].Equals(partner)) { aalLine.Append(MDLV2000Writer.FormatMDLInt(a + 1, 4)); aalLine.Append(MDLV2000Writer.FormatMDLInt(apoIdx, 4)); } } apoIdx++; } } } rootBlock.Append(aalLine.ToString()).Append(LSEP); } } } rootBlock.Append("M END").Append(LSEP).Append("$END CTAB").Append(LSEP); //Construct each R-group block var rgpBlock = new StringBuilder(); foreach (var rgrpNum in rGroupQuery.RGroupDefinitions.Keys) { var rgrpList = rGroupQuery.RGroupDefinitions[rgrpNum].RGroups; if (rgrpList != null && rgrpList.Count != 0) { rgpBlock.Append("$RGP").Append(LSEP);; rgpBlock.Append(MDLV2000Writer.FormatMDLInt(rgrpNum, 4)).Append(LSEP); foreach (var rgroup in rgrpList) { //CTAB block rgpBlock.Append("$CTAB").Append(LSEP); string ctab = GetCTAB(rgroup.Group); ctab = ctab.Replace(LSEP + "M END" + LSEP, ""); rgpBlock.Append(ctab).Append(LSEP); //The APO line IAtom firstAttachmentPoint = rgroup.FirstAttachmentPoint; IAtom secondAttachmentPoint = rgroup.SecondAttachmentPoint; int apoCount = 0; if (firstAttachmentPoint != null) { var apoLine = new StringBuilder(); for (int atIdx = 0; atIdx < rgroup.Group.Atoms.Count; atIdx++) { if (rgroup.Group.Atoms[atIdx].Equals(firstAttachmentPoint)) { apoLine.Append(MDLV2000Writer.FormatMDLInt((atIdx + 1), 4)); apoCount++; if (secondAttachmentPoint != null && secondAttachmentPoint.Equals(firstAttachmentPoint)) { apoLine.Append(MDLV2000Writer.FormatMDLInt(3, 4)); } else { apoLine.Append(MDLV2000Writer.FormatMDLInt(1, 4)); } } } if (secondAttachmentPoint != null && !secondAttachmentPoint.Equals(firstAttachmentPoint)) { for (int atIdx = 0; atIdx < rgroup.Group.Atoms.Count; atIdx++) { if (rgroup.Group.Atoms[atIdx].Equals(secondAttachmentPoint)) { apoCount++; apoLine.Append(MDLV2000Writer.FormatMDLInt((atIdx + 1), 4)); apoLine.Append(MDLV2000Writer.FormatMDLInt(2, 4)); } } } if (apoCount > 0) { apoLine.Insert(0, "M APO" + MDLV2000Writer.FormatMDLInt(apoCount, 3)); rgpBlock.Append(apoLine).Append(LSEP); } } rgpBlock.Append("M END").Append(LSEP); rgpBlock.Append("$END CTAB").Append(LSEP); } rgpBlock.Append("$END RGP").Append(LSEP); } } rgpBlock.Append("$END MOL").Append(LSEP); writer.Write(rootBlock.ToString()); writer.Write(rgpBlock.ToString()); writer.Flush(); } catch (IOException e) { Console.Error.WriteLine(e.StackTrace); throw new CDKException("Unexpected exception when writing RGFile" + LSEP + e.Message); } }
// 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> /// 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); }
/// <inheritdoc/> public override bool Equals(object obj) { return(atom.Equals(obj)); }
/// <summary> Get a list of all the paths between two atoms. /// <p/> /// If the two atoms are the same an empty list is returned. Note that this problem /// is NP-hard and so can take a long time for large graphs. /// /// </summary> /// <param name="atomContainer">The molecule to consider /// </param> /// <param name="start"> The starting Atom of the path /// </param> /// <param name="end"> The ending Atom of the path /// </param> /// <returns> A <code>List</code> containing all the paths between the specified atoms /// </returns> public static System.Collections.IList getAllPaths(IAtomContainer atomContainer, IAtom start, IAtom end) { allPaths = new System.Collections.ArrayList(); if (start.Equals(end)) return allPaths; findPathBetween(atomContainer, start, end, new System.Collections.ArrayList()); return allPaths; }
public static bool replaceAtomByAtom(IAtomContainer container, IAtom atom, IAtom newAtom) { if (!container.contains(atom)) { // it should complain return false; } else { container.setAtomAt(container.getAtomNumber(atom), newAtom); IElectronContainer[] electronContainers = container.ElectronContainers; for (int i = 0; i < electronContainers.Length; i++) { if (electronContainers[i] is IBond) { IBond bond = (IBond)electronContainers[i]; if (bond.contains(atom)) { for (int j = 0; j < bond.AtomCount; j++) { if (atom.Equals(bond.getAtomAt(j))) { bond.setAtomAt(newAtom, j); } } } } else if (electronContainers[i] is ILonePair) { ILonePair lonePair = (ILonePair)electronContainers[i]; if (atom.Equals(lonePair.Atom)) { lonePair.Atom = newAtom; } } } return true; } }