public void DoNotCreateCenterWhenSouthIsMissing() { IAtom focus = Atom("C", 0, 0.80d, 0.42d); IAtom north = Atom("C", 0, 0.80d, 1.24d); IAtom east = Atom("O", 1, 1.63d, 0.42d); IAtom west = Atom("H", 0, -0.02d, 0.42d); IBond[] bonds = new IBond[] { new Bond(focus, north), new Bond(focus, west), new Bond(focus, east) }; ITetrahedralChirality element = FischerRecognition.NewTetrahedralCenter(focus, bonds); Assert.IsNull(element); }
public void TestMap_Map_Map_EmptyMapping() { IChemObjectBuilder builder = ChemObjectBuilder.Instance; IAtom c1 = builder.NewAtom("C"); IAtom o2 = builder.NewAtom("O"); IAtom n3 = builder.NewAtom("N"); IAtom c4 = builder.NewAtom("C"); IAtom h5 = builder.NewAtom("H"); // new stereo element ITetrahedralChirality original = new TetrahedralChirality(c1, new IAtom[] { o2, n3, c4, h5 }, TetrahedralStereo.Clockwise); // map the existing element a new element - should through an IllegalArgumentException var map = new CDKObjectMap(); ITetrahedralChirality mapped = (ITetrahedralChirality)original.Clone(map); Assert.AreSame(original.ChiralAtom, mapped.ChiralAtom); }
/// <summary> /// Creates a new data model for chirality for the CIP rules based on a chirality definition /// in the CDK data model with <see cref="ITetrahedralChirality"/>. /// </summary> /// <param name="container"><see cref="IAtomContainer"/> to which the chiral atom belongs.</param> /// <param name="cdkChirality"><see cref="ITetrahedralChirality"/> object specifying the chirality.</param> public LigancyFourChirality(IAtomContainer container, ITetrahedralChirality cdkChirality) { this.ChiralAtom = cdkChirality.ChiralAtom; var ligandAtoms = cdkChirality.Ligands; this.ligands = new List <ILigand>(ligandAtoms.Count); var visitedAtoms = new VisitedAtoms(); foreach (var ligandAtom in ligandAtoms) { // ITetrahedralChirality stores a implicit hydrogen as the central atom if (ligandAtom == ChiralAtom) { this.ligands.Add(new ImplicitHydrogenLigand(container, visitedAtoms, ChiralAtom)); } else { this.ligands.Add(new Ligand(container, visitedAtoms, ChiralAtom, ligandAtom)); } } this.Stereo = cdkChirality.Stereo; }
public void DoNotCreateCenterWhenRotated() { IAtom focus = Atom("C", 0, 0.44d, 3.30d); IAtom north = Atom("C", 3, -0.16d, 3.86d); IAtom east = Atom("O", 1, 1.00d, 3.90d); IAtom south = Atom("C", 3, 1.05d, 2.74d); IAtom west = Atom("H", 0, -0.12d, 2.70d); IBond[] bonds = new IBond[] { new Bond(focus, west), new Bond(focus, north), new Bond(focus, south), new Bond(focus, east) }; ITetrahedralChirality element = FischerRecognition.NewTetrahedralCenter(focus, bonds); Assert.IsNull(element); }
public void TestNewTetrahedralChirality() { IChemObjectBuilder builder = RootObject.Builder; IAtomContainer molecule = builder.NewAtomContainer(); molecule.Atoms.Add(builder.NewAtom("Cl")); molecule.Atoms.Add(builder.NewAtom("C")); molecule.Atoms.Add(builder.NewAtom("Br")); molecule.Atoms.Add(builder.NewAtom("I")); molecule.Atoms.Add(builder.NewAtom("H")); molecule.AddBond(molecule.Atoms[0], molecule.Atoms[1], BondOrder.Single); molecule.AddBond(molecule.Atoms[1], molecule.Atoms[2], BondOrder.Single); molecule.AddBond(molecule.Atoms[1], molecule.Atoms[3], BondOrder.Single); molecule.AddBond(molecule.Atoms[1], molecule.Atoms[4], BondOrder.Single); IAtom[] ligands = new IAtom[] { molecule.Atoms[4], molecule.Atoms[3], molecule.Atoms[2], molecule.Atoms[0] }; ITetrahedralChirality chirality = builder.NewTetrahedralChirality(molecule.Atoms[1], ligands, TetrahedralStereo.Clockwise); Assert.IsNotNull(chirality); Assert.AreEqual(builder, chirality.Builder); }
public void CreateCenterWithThreeNeighbors_right() { IAtom focus = Atom("C", 0, 0.80d, 0.42d); IAtom north = Atom("C", 0, 0.80d, 1.24d); IAtom east = Atom("O", 1, 1.63d, 0.42d); IAtom south = Atom("C", 2, 0.80d, -0.41d); IBond[] bonds = new IBond[] { new Bond(focus, south), new Bond(focus, north), new Bond(focus, east) }; ITetrahedralChirality element = FischerRecognition.NewTetrahedralCenter(focus, bonds); Assert.AreSame(focus, element.ChiralAtom); Assert.AreEqual(TetrahedralStereo.AntiClockwise, element.Stereo); Assert.AreSame(north, element.Ligands[0]); Assert.AreSame(east, element.Ligands[1]); Assert.AreSame(south, element.Ligands[2]); Assert.AreSame(focus, element.Ligands[3]); }
/// <summary> /// Verify the tetrahedral stereochemistry (clockwise/anticlockwise) of atom /// <paramref name="u"/> is preserved in the target when the <paramref name="mapping"/> is used. /// </summary> /// <param name="u">tetrahedral index in the target</param> /// <param name="mapping">mapping of vertices</param> /// <returns>the tetrahedral configuration is preserved</returns> private bool CheckTetrahedral(int u, int[] mapping) { int v = mapping[u]; if (targetTypes[v] != StereoType.Unset && targetTypes[v] != StereoType.Tetrahedral) { return(false); } ITetrahedralChirality queryElement = (ITetrahedralChirality)queryElements[u]; ITetrahedralChirality targetElement = (ITetrahedralChirality)targetElements[v]; SMARTSAtom queryAtom = (SMARTSAtom)query.Atoms[u]; IAtom targetAtom = target.Atoms[v]; int[] us = Neighbors(queryElement, queryMap); us = Map(u, v, us, mapping); int p = PermutationParity(us); // check if unspecified was allowed if (targetTypes[v] == StereoType.Unset) { if (queryAtom is SMARTSAtom) { return(((SMARTSAtom)queryAtom).ChiralityMatches(targetAtom, 0, p)); } else { return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, 0)); } } // target was non-tetrahedral if (targetTypes[v] != StereoType.Tetrahedral) { return(false); } int[] vs = Neighbors(targetElement, targetMap); int q = PermutationParity(vs) * Parity(targetElement.Stereo); if (queryAtom is SMARTSAtom) { return(((SMARTSAtom)queryAtom).ChiralityMatches(targetAtom, q, p)); } else { q *= p; if (q < 0) { return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, (int)StereoConfigurations.Left)); } else if (q > 0) { return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, (int)StereoConfigurations.Right)); } else { return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, 0)); } } }
/// <summary> /// Utility function for computing CTfile windings. The return value is adjusted /// to the MDL's model (look to lowest rank/highest number) from CDK's model (look from /// first). /// </summary> /// <param name="idxs">atom/bond index lookup</param> /// <param name="stereo">the tetrahedral configuration</param> /// <returns>winding to write to molfile</returns> private static TetrahedralStereo GetLocalParity(Dictionary <IChemObject, int> idxs, ITetrahedralChirality stereo) { var neighbours = stereo.Ligands; var neighbourIdx = new int[neighbours.Count]; Trace.Assert(neighbours.Count == 4); for (int i = 0; i < 4; i++) { // impl H is last if (neighbours[i] == stereo.ChiralAtom) { neighbourIdx[i] = int.MaxValue; } else { neighbourIdx[i] = idxs[neighbours[i]]; } } // determine winding swaps bool inverted = false; for (int i = 0; i < 4; i++) { for (int j = i + 1; j < 4; j++) { if (neighbourIdx[i] > neighbourIdx[j]) { inverted = !inverted; } } } // CDK winding is looking from the first atom, MDL is looking // towards the last so we invert by default, note inverting twice // would be a no op and is omitted return(inverted ? stereo.Stereo : stereo.Stereo.Invert()); }
void Main() { IAtomContainer someMolecule = null; StereoElementFactory someFactory = null; { #region IAtomContainer container = someMolecule; StereoElementFactory stereo = StereoElementFactory.Using2DCoordinates(container).InterpretProjections(Projection.Haworth); // set the elements replacing any existing elements container.SetStereoElements(stereo.CreateAll()); // adding elements individually is also possible but existing elements are // are not removed foreach (var element in stereo.CreateAll()) { container.StereoElements.Add(element); } #endregion } { #region CreateTetrahedral_int StereoElementFactory factory = someFactory; // 2D/3D IAtomContainer container = someMolecule; // container for (int v = 0; v < container.Atoms.Count; v++) { // ... verify v is a stereo atom ... ITetrahedralChirality element = factory.CreateTetrahedral(v, null); if (element != null) { container.StereoElements.Add(element); } } #endregion } { #region CreateTetrahedral_IAtom StereoElementFactory factory = someFactory; // 2D/3D IAtomContainer container = someMolecule; // container foreach (var atom in container.Atoms) { // ... verify atom is a stereo atom ... ITetrahedralChirality element = factory.CreateTetrahedral(atom, null); if (element != null) { container.StereoElements.Add(element); } } #endregion } { #region CreateGeometric_IBond StereoElementFactory factory = someFactory; // 2D/3D IAtomContainer container = someMolecule; // container foreach (var bond in container.Bonds) { if (bond.Order != BondOrder.Double) { continue; } // ... verify bond is a stereo bond... IDoubleBondStereochemistry element = factory.CreateGeometric(bond, null); if (element != null) { container.StereoElements.Add(element); } } #endregion } { #region CreateExtendedTetrahedral StereoElementFactory factory = someFactory; // 2D/3D IAtomContainer container = someMolecule; // container for (int v = 0; v < container.Atoms.Count; v++) { // ... verify v is a stereo atom ... ExtendedTetrahedral element = factory.CreateExtendedTetrahedral(v, null); if (element != null) { container.StereoElements.Add(element); } } #endregion } { IAtomContainer container = someMolecule; // container #region InterpretProjections StereoElementFactory factory = StereoElementFactory.Using2DCoordinates(container) .InterpretProjections(Projection.Fischer, Projection.Haworth); #endregion } }