/// <summary> /// RemovePseudoAtoms /// </summary> /// <param name="mol"></param> /// <returns>Pseudo atom count</returns> public static int RemovePseudoAtoms(IAtomContainer mol) { List <IAtom> pseudoAtoms = new List <IAtom>(); for (int ai = 0; ai < mol.Atoms.Count; ai++) { IAtom atom = mol.Atoms[ai]; if (atom is IPseudoAtom) { pseudoAtoms.Add(atom); } } if (pseudoAtoms.Count == 0) { return(0); } foreach (IAtom atom in pseudoAtoms) { mol.RemoveAtom(atom); } AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(mol); mol = AtomContainerManipulator.SuppressHydrogens(mol); GetHydrogenAdder().AddImplicitHydrogens(mol); return(pseudoAtoms.Count); }
public override void TestBug706786() { IAtomContainer superStructure = Bug706786_1(); IAtomContainer subStructure = Bug706786_2(); AddImplicitHydrogens(superStructure); AddImplicitHydrogens(subStructure); // SMARTS is now correct and D will include H atoms, CDK had this wrong // for years (had it has non-H count). Whilst you can set the optional // SMARTS flavor CDK_LEGACY this is not correct AtomContainerManipulator.SuppressHydrogens(superStructure); AtomContainerManipulator.SuppressHydrogens(subStructure); IFingerprinter fpr = GetBitFingerprinter(); IBitFingerprint superBits = fpr.GetBitFingerprint(superStructure); IBitFingerprint subBits = fpr.GetBitFingerprint(subStructure); Assert.IsTrue(BitArrays.Equals( AsBitSet(0, 11, 13, 17, 40, 48, 136, 273, 274, 278, 286, 294, 299, 301, 304, 306), superBits.AsBitSet())); Assert.IsTrue(BitArrays.Equals( AsBitSet(1, 17, 273, 274, 278, 294, 306), subBits.AsBitSet())); }
/// <summary> /// Remove the following features from a molecule /// - Atom non-standard mass /// - Stereo chemistry /// - explicit hydrogens /// </summary> /// <param name="src"></param> /// <returns>Modified mol</returns> public static IAtomContainer RemoveIsotopesStereoExplicitHydrogens( IAtomContainer src) { IAtom[] atoms = new IAtom[src.Atoms.Count]; IBond[] bonds = new IBond[src.Bonds.Count]; IChemObjectBuilder builder = src.Builder; for (int i = 0; i < atoms.Length; i++) { IAtom atom = src.Atoms[i]; IAtom atom2 = builder.NewAtom(atom.Symbol); SetImplicitHydrogenCount(atom2, GetImplicitHydrogenCount(atom)); atom2.Point2D = atom.Point2D; atoms[i] = atom2; } for (int i = 0; i < bonds.Length; i++) { IBond bond = src.Bonds[i]; int u = bond.Atoms[0].Index; int v = bond.Atoms[1].Index; IBond bond2 = builder.NewBond(atoms[u], atoms[v]); bond2.IsAromatic = bond.IsAromatic; bond2.IsInRing = bond.IsInRing; bond2.Order = bond.Order; bond2.IsAromatic = bond.IsAromatic; bond2.IsSingleOrDouble = bond.IsSingleOrDouble; bonds[i] = bond2; } IAtomContainer dest = ChemObjectBuilder.Instance.NewAtomContainer(); dest.SetAtoms(atoms); dest.SetBonds(bonds); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(dest); dest = AtomContainerManipulator.SuppressHydrogens(dest); GetHydrogenAdder().AddImplicitHydrogens(dest); return(dest); }
/// <summary> /// Overloaded <see cref="GetTautomers(IAtomContainer)"/> to get tautomers for an input molecule with the InChI already /// provided as input argument. /// </summary> /// <param name="mol">and input molecule for which to generate tautomers</param> /// <param name="inchi">InChI for the input molecule</param> /// <param name="amap">ordering of the molecules atoms in the InChI</param> /// <returns>a list of tautomers</returns> /// <exception cref="CDKException"></exception> private List <IAtomContainer> GetTautomers(IAtomContainer mol, string inchi, long[] amap) { //Initial checks if (mol == null || inchi == null) { throw new CDKException("Please provide a valid input molecule and its corresponding InChI value."); } // shallow copy since we will suppress hydrogens mol = mol.Builder.NewAtomContainer(mol); var tautomers = new List <IAtomContainer>(); if (!inchi.Contains("(H")) { //No mobile H atoms according to InChI, so bail out. tautomers.Add(mol); return(tautomers); } //Preparation: translate the InChi var inchiAtomsByPosition = GetElementsByPosition(inchi, mol); var inchiMolGraph = ConnectAtoms(inchi, mol, inchiAtomsByPosition); if (amap != null && amap.Length == mol.Atoms.Count) { for (int i = 0; i < amap.Length; i++) { mol.Atoms[i].Id = amap[i].ToString(NumberFormatInfo.InvariantInfo); } mol = AtomContainerManipulator.SuppressHydrogens(mol); } else { mol = AtomContainerManipulator.SuppressHydrogens(mol); MapInputMoleculeToInChIMolgraph(inchiMolGraph, mol); } var mobHydrAttachPositions = new List <int>(); var totalMobHydrCount = ParseMobileHydrogens(mobHydrAttachPositions, inchi); tautomers = ConstructTautomers(mol, mobHydrAttachPositions, totalMobHydrCount); //Remove duplicates return(RemoveDuplicates(tautomers)); }
public override void TestBug706786() { IAtomContainer superStructure = Bug706786_1(); IAtomContainer subStructure = Bug706786_2(); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(superStructure); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(subStructure); AddImplicitHydrogens(superStructure); AddImplicitHydrogens(subStructure); // SMARTS is now correct and D will include H atoms, CDK had this wrong // for years (had it has non-H count). Whilst you can set the optional // SMARTS flavor CDK_LEGACY this is not correct AtomContainerManipulator.SuppressHydrogens(superStructure); AtomContainerManipulator.SuppressHydrogens(subStructure); IFingerprinter fpr = new EStateFingerprinter(); IBitFingerprint superBits = fpr.GetBitFingerprint(superStructure); IBitFingerprint subBits = fpr.GetBitFingerprint(subStructure); Assert.IsTrue(BitArrays.Equals(AsBitSet(6, 11, 12, 15, 16, 18, 33, 34, 35), superBits.AsBitSet())); Assert.IsTrue(BitArrays.Equals(AsBitSet(8, 11, 16, 35), subBits.AsBitSet())); }
/// <summary> /// Integrate MMP difference and common fragments /// </summary> /// <param name="smilesFrags"></param> /// <returns>Molfile of integrated mol with difference fragment hilighted via special atom isotope values </returns> public string IntegrateAndHilightMmpStructure( string smilesFrags) { IAtomContainer mol; IAtom atom; string frag, context1, context2, molfile, chime = "", molfile2 = ""; int ai, atomCount; //IsotopeConversionTest(""); // debug DateTime t0 = DateTime.Now; try { Lex.Split(smilesFrags, ":", out frag, out context1, out context2); if (Lex.Eq(context2, "NULL")) { context2 = ""; // fixup for undefined Redshift fragment smiles fragment represented as "NULL" rather than a blank string } mol = SmilesToAtomContainer(frag); atomCount = mol.Atoms.Count; for (ai = 0; ai < atomCount; ai++) // set isotope labels to mark difference frag { atom = mol.Atoms[ai]; int mn = GetMassNumber(atom); if (mn == 0) { SetMassNumber(atom, hilightIsotopeValue); // mark with special value } else if (mn > 0) { SetMassNumber(atom, -mn); // negate original value to indicate part of difference frag } } if (Lex.IsDefined(context1)) { JoinMmpFragments(mol, context1, 1); atomCount = mol.Atoms.Count; } if (Lex.IsDefined(context2)) { JoinMmpFragments(mol, context2, 2); atomCount = mol.Atoms.Count; } mol = AtomContainerManipulator.SuppressHydrogens(mol); // fix potential valency issues atomCount = mol.Atoms.Count; for (ai = 0; ai < atomCount; ai++) // clean up structure for good display { atom = mol.Atoms[ai]; if (atom.Valency != null && atom.Valency.Value != 0) { atom.Valency = 0; } if (GetImplicitHydrogenCount(atom) != 0) { SetImplicitHydrogenCount(atom, 0); } } AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(mol); mol = AtomContainerManipulator.SuppressHydrogens(mol); GetHydrogenAdder().AddImplicitHydrogens(mol); mol = GenerateCoordinates(mol); atomCount = mol.Atoms.Count; molfile = ConvertIsotopeValuesToHilighting(mol); // about 3.0 ms per IntegrateAndHilightMmpStructure call double msTime = TimeOfDay.Delta(t0); IntegrateAndHilightMmpStructureCount++; IntegrateAndHilightMmpStructureTotalTime += msTime; IntegrateAndHilightMmpStructureAvgTime = IntegrateAndHilightMmpStructureTotalTime / IntegrateAndHilightMmpStructureCount; return(molfile); } catch (Exception ex) { string msg = "Error integrating Smiles Fragments: " + smilesFrags + DebugLog.FormatExceptionMessage(ex, true); DebugLog.Message(msg); return(""); } }