public void TestAutomatic_Set_Active_Bond() { /* ionize all possible double bonds */ IAtomContainer reactant = builder.NewAtomContainer();//Miles("C=CC") reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.AddBond(reactant.Atoms[0], reactant.Atoms[1], BondOrder.Double); reactant.AddBond(reactant.Atoms[1], reactant.Atoms[2], BondOrder.Single); AddExplicitHydrogens(reactant); var setOfReactants = ChemObjectBuilder.Instance.NewAtomContainerSet(); setOfReactants.Add(reactant); /* initiate */ AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(reactant); MakeSureAtomTypesAreRecognized(reactant); IReactionProcess type = new ElectronImpactPDBReaction(); var setOfReactions = type.Initiate(setOfReactants, null); Assert.AreEqual(2, setOfReactions.Count); IAtomContainer molecule = setOfReactions[0].Products[0]; Assert.AreEqual(1, molecule.Atoms[0].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[1]).Count()); molecule = setOfReactions[1].Products[0]; Assert.AreEqual(1, molecule.Atoms[1].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[0]).Count()); }
/// <summary> /// set the active center for this molecule. /// The active center will be those which correspond with X=Y. /// </summary> /// <param name="reactant">The molecule to set the activity</param> private static void SetActiveCenters(IAtomContainer reactant) { if (AtomContainerManipulator.GetTotalCharge(reactant) != 0) { return; } foreach (var bondi in reactant.Bonds) { if (((bondi.Order == BondOrder.Double) || (bondi.Order == BondOrder.Triple))) { int chargeAtom0 = bondi.Begin.FormalCharge ?? 0; int chargeAtom1 = bondi.End.FormalCharge ?? 0; if (chargeAtom0 >= 0 && chargeAtom1 >= 0 && !reactant.GetConnectedSingleElectrons(bondi.Begin).Any() && !reactant.GetConnectedSingleElectrons(bondi.End).Any() && !reactant.GetConnectedLonePairs(bondi.Begin).Any() && !reactant.GetConnectedLonePairs(bondi.End).Any()) { bondi.IsReactiveCenter = true; bondi.Begin.IsReactiveCenter = true; bondi.End.IsReactiveCenter = true; } } } }
internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, BondCheck bondChecker) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // 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, bondChecker); } foreach (var bondi in reactant.Bonds) { IAtom atom1 = bondi.Begin; IAtom atom2 = bondi.End; if (bondi.IsReactiveCenter && bondChecker(bondi) && atom1.IsReactiveCenter && atom2.IsReactiveCenter && (atom1.FormalCharge ?? 0) == 0 && (atom2.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atom1).Any() && !reactant.GetConnectedSingleElectrons(atom2).Any()) { for (int j = 0; j < 2; j++) { var atomList = new List <IAtom>(); if (j == 0) { atomList.Add(atom1); atomList.Add(atom2); } else { atomList.Add(atom2); atomList.Add(atom1); } var bondList = new List <IBond> { bondi }; IChemObjectSet <IAtomContainer> moleculeSet = reactant.Builder.NewAtomContainerSet(); moleculeSet.Add(reactant); IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, bondList); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } } return(setOfReactions); }
/// <summary> /// set the active center for this molecule. /// The active center will be those which correspond with X=Y-Z-H. /// <pre> /// X: Atom /// =: bond /// Y: Atom /// -: bond /// Z: Atom /// -: bond /// H: Atom /// </pre> /// </summary> /// <param name="reactant">The molecule to set the activity</param> private static void SetActiveCenters(IAtomContainer reactant) { foreach (var atomi in reactant.Atoms) { if ((atomi.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomi).Any()) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.Order == BondOrder.Double) { IAtom atomj = bondi.GetOther(atomi); if ((atomj.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomj).Any()) { foreach (var bondj in reactant.GetConnectedBonds(atomj)) { if (bondj.Equals(bondi)) { continue; } if (bondj.Order == BondOrder.Single) { IAtom atomk = bondj.GetOther(atomj); if ((atomk.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomk).Any() ) { foreach (var bondk in reactant.GetConnectedBonds(atomk)) { if (bondk.Equals(bondj)) { continue; } if (bondk.Order == BondOrder.Single) { IAtom atoml = bondk.GetOther(atomk); // Atom pos 4 if (atoml.AtomicNumber.Equals(AtomicNumbers.H)) { atomi.IsReactiveCenter = true; atomj.IsReactiveCenter = true; atomk.IsReactiveCenter = true; atoml.IsReactiveCenter = true; bondi.IsReactiveCenter = true; bondj.IsReactiveCenter = true; bondk.IsReactiveCenter = true; } } } } } } } } } } } }
public void TestAutomatic_Set_Active_Bond2() { /* ionize >C=C< , set the reactive center */ IAtomContainer reactant = builder.NewAtomContainer();//CreateFromSmiles("C=CCC(=O)CC") reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("O")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.AddBond(reactant.Atoms[0], reactant.Atoms[1], BondOrder.Double); reactant.AddBond(reactant.Atoms[1], reactant.Atoms[2], BondOrder.Single); reactant.AddBond(reactant.Atoms[2], reactant.Atoms[3], BondOrder.Single); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[4], BondOrder.Double); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[5], BondOrder.Single); reactant.AddBond(reactant.Atoms[5], reactant.Atoms[6], BondOrder.Single); AddExplicitHydrogens(reactant); var setOfReactants = ChemObjectBuilder.Instance.NewAtomContainerSet(); setOfReactants.Add(reactant); /* initiate */ AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(reactant); MakeSureAtomTypesAreRecognized(reactant); var type = new ElectronImpactPDBReaction(); var paramList = new List <IParameterReaction>(); var param = new SetReactionCenter { IsSetParameter = false }; paramList.Add(param); type.ParameterList = paramList; var setOfReactions = type.Initiate(setOfReactants, null); Assert.AreEqual(3, setOfReactions.Count); IAtomContainer molecule = setOfReactions[0].Products[0]; Assert.AreEqual(1, molecule.Atoms[0].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[1]).Count()); molecule = setOfReactions[1].Products[0]; Assert.AreEqual(1, molecule.Atoms[1].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[0]).Count()); Assert.AreEqual(17, setOfReactions[0].Mappings.Count); }
public override void TestInitiate_IAtomContainerSet_IAtomContainerSet() { /* Ionize(>C=O): C=CCC(=O)CC -> C=CCC(=O*)CC , set the reactive center */ IAtomContainer reactant = builder.NewAtomContainer();//CreateFromSmiles("C=CCC(=O)CC") reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("O")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.AddBond(reactant.Atoms[0], reactant.Atoms[1], BondOrder.Double); reactant.AddBond(reactant.Atoms[1], reactant.Atoms[2], BondOrder.Single); reactant.AddBond(reactant.Atoms[2], reactant.Atoms[3], BondOrder.Single); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[4], BondOrder.Double); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[5], BondOrder.Single); reactant.AddBond(reactant.Atoms[5], reactant.Atoms[6], BondOrder.Single); AddExplicitHydrogens(reactant); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(reactant); CDK.LonePairElectronChecker.Saturate(reactant); foreach (var atom in reactant.Atoms) { if (reactant.GetConnectedLonePairs(atom).Count() > 0) { atom.IsReactiveCenter = true; } } var setOfReactants = ChemObjectBuilder.Instance.NewAtomContainerSet(); setOfReactants.Add(reactant); /* initiate */ MakeSureAtomTypesAreRecognized(reactant); IReactionProcess type = new ElectronImpactNBEReaction(); var paramList = new List <IParameterReaction>(); IParameterReaction param = new SetReactionCenter { IsSetParameter = true }; paramList.Add(param); type.ParameterList = paramList; var setOfReactions = type.Initiate(setOfReactants, null); Assert.AreEqual(1, setOfReactions.Count); Assert.AreEqual(1, setOfReactions[0].Products.Count); IAtomContainer molecule = setOfReactions[0].Products[0]; Assert.AreEqual(1, molecule.Atoms[4].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[4]).Count()); Assert.IsTrue(setOfReactions[0].Mappings.Any()); }
/// <summary> /// set the active center for this molecule. /// The active center will be those which correspond with [A+]=B. /// <pre> /// A: Atom with positive charge /// =: Double bond /// B: Atom /// </pre> /// </summary> /// <param name="reactant">The molecule to set the activity</param> private static void SetActiveCenters(IAtomContainer reactant) { foreach (var atomi in reactant.Atoms) { if (atomi.FormalCharge == 1) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.Order != BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if (atomj.FormalCharge == 0) { if (!reactant.GetConnectedSingleElectrons(atomj).Any()) { atomi.IsReactiveCenter = true; bondi.IsReactiveCenter = true; atomj.IsReactiveCenter = true; } } } } } } }
/// <summary> /// Generate the displayed atom symbol for an atom in given structure with the specified hydrogen /// position. /// </summary> /// <param name="container">structure to which the atom belongs</param> /// <param name="atom">the atom to generate the symbol for</param> /// <param name="position">the hydrogen position</param> /// <param name="model">additional rendering options</param> /// <returns>atom symbol</returns> public AtomSymbol GenerateSymbol(IAtomContainer container, IAtom atom, HydrogenPosition position, RendererModel model) { if (atom is IPseudoAtom pAtom) { if (pAtom.AttachPointNum <= 0) { if ("*".Equals(pAtom.Label, StringComparison.Ordinal)) { var mass = pAtom.MassNumber ?? 0; var charge = pAtom.FormalCharge ?? 0; var hcnt = pAtom.ImplicitHydrogenCount ?? 0; var nrad = container.GetConnectedSingleElectrons(atom).Count(); if (mass != 0 || charge != 0 || hcnt != 0) { return(GeneratePeriodicSymbol(0, hcnt, mass, charge, nrad, position)); } } return(GeneratePseudoSymbol(AccessPseudoLabel(pAtom, "?"), position)); } else { return(null); // attach point drawn in bond generator } } else { var number = atom.AtomicNumber; // unset the mass if it's the major isotope (could be an option) var mass = atom.MassNumber; if (number != 0 && mass != null && model != null && model.GetOmitMajorIsotopes() && IsMajorIsotope(number, mass.Value)) { mass = null; } return(GeneratePeriodicSymbol( number, atom.ImplicitHydrogenCount ?? 0, mass ?? -1, atom.FormalCharge ?? 0, container.GetConnectedSingleElectrons(atom).Count(), position)); } }
private static void SetActiveCenters(IAtomContainer reactant, CheckReactant checkReatant, CheckReactantAtom checkReatantAtom, CheckAtom checkAtom) { if (checkReatant != null && !checkReatant(reactant)) { return; } foreach (var atomi in reactant.Atoms) { if (checkReatantAtom(reactant, atomi)) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.Order == BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if ((atomj.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomj).Any()) { foreach (var bondj in reactant.GetConnectedBonds(atomj)) { if (bondj.Equals(bondi)) { continue; } if (bondj.Order == BondOrder.Double) { IAtom atomk = bondj.GetOther(atomj); if (checkAtom(atomk) && !reactant.GetConnectedSingleElectrons(atomk).Any()) { atomi.IsReactiveCenter = true; atomj.IsReactiveCenter = true; atomk.IsReactiveCenter = true; bondi.IsReactiveCenter = true; bondj.IsReactiveCenter = true; } } } } } } } } }
public override void TestInitiate_IAtomContainerSet_IAtomContainerSet() { /* Ionize(>C-C<): C=CCC -> C=C* + C+ , set the reactive center */ var setOfReactants = GetExampleReactants(); IAtomContainer reactant = setOfReactants[0]; foreach (var bond in reactant.Bonds) { IAtom atom1 = bond.Atoms[0]; IAtom atom2 = bond.Atoms[1]; if (bond.Order == BondOrder.Single && atom1.Symbol.Equals("C") && atom2.Symbol.Equals("C")) { bond.IsReactiveCenter = true; atom1.IsReactiveCenter = true; atom2.IsReactiveCenter = true; } } Assert.AreEqual(0, reactant.SingleElectrons.Count); /* initiate */ var type = new ElectronImpactSDBReaction(); var paramList = new List <IParameterReaction>(); var param = new SetReactionCenter { IsSetParameter = true }; paramList.Add(param); type.ParameterList = paramList; var setOfReactions = type.Initiate(setOfReactants, null); Assert.AreEqual(2, setOfReactions.Count); Assert.AreEqual(2, setOfReactions[0].Products.Count); IAtomContainer molecule1 = setOfReactions[0].Products[0];//[H][C+]=C([H])[H] Assert.AreEqual(1, molecule1.Atoms[1].FormalCharge.Value); Assert.AreEqual(0, molecule1.SingleElectrons.Count); IAtomContainer molecule2 = setOfReactions[0].Products[1];//[H][C*]([H])[H] Assert.AreEqual(1, molecule2.SingleElectrons.Count); Assert.AreEqual(1, molecule2.GetConnectedSingleElectrons(molecule2.Atoms[0]).Count()); Assert.IsTrue(setOfReactions[0].Mappings.Any()); Assert.AreEqual(2, setOfReactions[1].Products.Count); molecule1 = setOfReactions[1].Products[0];//[H]C=[C*]([H])[H] Assert.AreEqual(1, molecule1.GetConnectedSingleElectrons(molecule1.Atoms[1]).Count()); molecule2 = setOfReactions[1].Products[1];//[H][C+]([H])[H] Assert.AreEqual(0, molecule2.SingleElectrons.Count); Assert.AreEqual(1, molecule2.Atoms[0].FormalCharge.Value); }
private static void SetActiveCenters(IAtomContainer reactant, BondCheck bondCheck) { foreach (var bond in reactant.Bonds) { var atom1 = bond.Begin; var atom2 = bond.End; if ((bondCheck == null || bondCheck(bond)) && (atom1.FormalCharge ?? 0) == 0 && (atom2.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atom1).Any() && !reactant.GetConnectedSingleElectrons(atom2).Any()) { atom1.IsReactiveCenter = true; atom2.IsReactiveCenter = true; bond.IsReactiveCenter = true; } } }
private static void SetActiveCenters(IAtomContainer reactant, BondCheck bondChecker) { foreach (var bondi in reactant.Bonds) { IAtom atom1 = bondi.Begin; IAtom atom2 = bondi.End; if (bondChecker(bondi) && (atom1.FormalCharge ?? 0) == 0 && (atom2.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atom1).Any() && !reactant.GetConnectedSingleElectrons(atom2).Any()) { bondi.IsReactiveCenter = true; atom1.IsReactiveCenter = true; atom2.IsReactiveCenter = true; } } }
internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, bool isReverse, CheckReactantAtom checkReactantAtom, CheckAtom checkAtom, CheckBond checkBond) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // 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, checkReactantAtom, checkAtom, checkBond); } foreach (var atomi in reactant.Atoms) { if (atomi.IsReactiveCenter && checkReactantAtom(reactant, atomi)) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.IsReactiveCenter && checkBond(bondi)) { IAtom atomj = bondi.GetOther(atomi); if (atomj.IsReactiveCenter && checkAtom(atomj) && !reactant.GetConnectedSingleElectrons(atomj).Any()) { IAtom[] atomList; if (isReverse) { atomList = new[] { atomj, atomi } } ; else { atomList = new[] { atomi, atomj } }; var bondList = new[] { bondi }; IChemObjectSet <IAtomContainer> moleculeSet = reactant.Builder.NewChemObjectSet <IAtomContainer>(); moleculeSet.Add(reactant); IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, bondList); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } } } } return(setOfReactions); }
/// <summary> /// set the active center for this molecule. The active center /// will be heteroatoms which contain at least one group of /// lone pair electrons. /// </summary> /// <param name="reactant">The molecule to set the activity</param> private static void SetActiveCenters(IAtomContainer reactant) { foreach (var atom in reactant.Atoms) { if (reactant.GetConnectedLonePairs(atom).Any() && !reactant.GetConnectedSingleElectrons(atom).Any()) { atom.IsReactiveCenter = true; } } }
internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, string atomSymbol) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; IParameterReaction ipr = base.GetParameterClass(typeof(SetReactionCenter)); if (ipr != null && !ipr.IsSetParameter) { SetActiveCenters(reactant); } if (AtomContainerManipulator.GetTotalCharge(reactant) > 0) { return(setOfReactions); } foreach (var atomi in reactant.Atoms) { if (atomi.IsReactiveCenter && (atomi.FormalCharge ?? 0) <= 0 && reactant.GetConnectedLonePairs(atomi).Any() && !reactant.GetConnectedSingleElectrons(atomi).Any()) { var atomList = new List <IAtom> { atomi }; IAtom atomH = reactant.Builder.NewAtom(atomSymbol); atomH.FormalCharge = 1; atomList.Add(atomH); var moleculeSet = reactant.Builder.NewAtomContainerSet(); moleculeSet.Add(reactant); IAtomContainer adduct = reactant.Builder.NewAtomContainer(); adduct.Atoms.Add(atomH); moleculeSet.Add(adduct); IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, null); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } return(setOfReactions); }
/// <summary> /// Performs a BreadthFirstSearch in an AtomContainer starting with a /// particular sphere, which usually consists of one start atom. While /// searching the graph, the method marks each visited atom. It then puts all /// the atoms connected to the atoms in the given sphere into a new vector /// which forms the sphere to search for the next recursive method call. All /// atoms that have been visited are put into a molecule container. This /// BreadthFirstSearch does thus find the connected graph for a given start /// atom. /// <para>IMPORTANT: this method does not reset the VISITED flags, which must be /// done if calling this method twice! /// </para> /// </summary> /// <param name="atomContainer">The AtomContainer to be searched</param> /// <param name="sphere">A sphere of atoms to start the search with</param> /// <param name="molecule">A molecule into which all the atoms and bonds are stored that are found during search</param> /// <param name="max">max</param> public static void BreadthFirstSearch(IAtomContainer atomContainer, IEnumerable <IAtom> sphere, IAtomContainer molecule, int max) { IAtom nextAtom; List <IAtom> newSphere = new List <IAtom>(); foreach (var atom in sphere) { molecule.Atoms.Add(atom); // first copy LonePair's and SingleElectron's of this Atom as they need // to be copied too var lonePairs = atomContainer.GetConnectedLonePairs(atom); foreach (var lonePair in lonePairs) { molecule.LonePairs.Add(lonePair); } var singleElectrons = atomContainer.GetConnectedSingleElectrons(atom); foreach (var singleElectron in singleElectrons) { molecule.SingleElectrons.Add(singleElectron); } // now look at bonds var bonds = atomContainer.GetConnectedBonds(atom); foreach (var bond in bonds) { nextAtom = bond.GetOther(atom); if (!bond.IsVisited) { molecule.Atoms.Add(nextAtom); molecule.Bonds.Add(bond); bond.IsVisited = true; } if (!nextAtom.IsVisited) { newSphere.Add(nextAtom); nextAtom.IsVisited = true; } } if (max > -1 && molecule.Atoms.Count > max) { return; } } if (newSphere.Count > 0) { BreadthFirstSearch(atomContainer, newSphere, molecule, max); } }
public void TestSpinMultiplicity() { var mol = new AtomContainer(); Atom atom = new Atom("C"); mol.Atoms.Add(atom); mol.SingleElectrons.Add(new SingleElectron(atom)); IAtomContainer roundTrippedMol = CMLRoundTripTool.RoundTripMolecule(convertor, mol); Assert.AreEqual(1, roundTrippedMol.Atoms.Count); Assert.AreEqual(1, roundTrippedMol.GetElectronContainers().Count()); IAtom roundTrippedAtom = roundTrippedMol.Atoms[0]; Assert.AreEqual(1, roundTrippedMol.GetConnectedSingleElectrons(roundTrippedAtom).Count()); }
/// <summary> /// Initiate process. /// It is needed to call the addExplicitHydrogensToSatisfyValency /// from the class tools.HydrogenAdder. /// </summary> /// <param name="reactants">Reactants of the reaction</param> /// <param name="agents">Agents of the reaction (Must be in this case null)</param> /// <exception cref="CDKException"> Description of the Exception</exception> public IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents) { Debug.WriteLine("initiate reaction: ElectronImpactNBEReaction"); if (reactants.Count != 1) { throw new CDKException("ElectronImpactNBEReaction only expects one reactant"); } if (agents != null) { throw new CDKException("ElectronImpactNBEReaction don't expects agents"); } IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // 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); } foreach (var atom in reactant.Atoms) { if (atom.IsReactiveCenter && reactant.GetConnectedLonePairs(atom).Any() && !reactant.GetConnectedSingleElectrons(atom).Any()) { var atomList = new List <IAtom> { atom }; IChemObjectSet <IAtomContainer> moleculeSet = reactant.Builder.NewAtomContainerSet(); moleculeSet.Add(reactant); IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, null); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } return(setOfReactions); }
private static void SetActiveCenters(IAtomContainer reactant) { if (AtomContainerManipulator.GetTotalCharge(reactant) > 0) { return; } foreach (var atomi in reactant.Atoms) { if ((atomi.FormalCharge ?? 0) <= 0 && reactant.GetConnectedLonePairs(atomi).Any() && !reactant.GetConnectedSingleElectrons(atomi).Any()) { atomi.IsReactiveCenter = true; } } }
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 void TestAutomatic_Set_Active_Atom() { // Ionize(>C=O): C=CCC(=O)CC -> C=CCC(=O*)CC, without setting the // reactive center IAtomContainer reactant = builder.NewAtomContainer();//CreateFromSmiles("C=CCC(=O)CC") reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("O")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.Atoms.Add(builder.NewAtom("C")); reactant.AddBond(reactant.Atoms[0], reactant.Atoms[1], BondOrder.Double); reactant.AddBond(reactant.Atoms[1], reactant.Atoms[2], BondOrder.Single); reactant.AddBond(reactant.Atoms[2], reactant.Atoms[3], BondOrder.Single); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[4], BondOrder.Double); reactant.AddBond(reactant.Atoms[3], reactant.Atoms[5], BondOrder.Single); reactant.AddBond(reactant.Atoms[5], reactant.Atoms[6], BondOrder.Single); AddExplicitHydrogens(reactant); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(reactant); CDK.LonePairElectronChecker.Saturate(reactant); var setOfReactants = ChemObjectBuilder.Instance.NewAtomContainerSet(); setOfReactants.Add(reactant); /* initiate */ MakeSureAtomTypesAreRecognized(reactant); IReactionProcess type = new ElectronImpactNBEReaction(); var setOfReactions = type.Initiate(setOfReactants, null); Assert.AreEqual(1, setOfReactions.Count); Assert.AreEqual(1, setOfReactions[0].Products.Count); IAtomContainer molecule = setOfReactions[0].Products[0]; Assert.AreEqual(1, molecule.Atoms[4].FormalCharge.Value); Assert.AreEqual(1, molecule.GetConnectedSingleElectrons(molecule.Atoms[4]).Count()); }
private static void SetActiveCenters(IAtomContainer reactant, CheckReactantAtom checkReactantAtom, CheckAtom checkAtom, CheckBond checkBond) { foreach (var atomi in reactant.Atoms) { if (checkReactantAtom(reactant, atomi)) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (checkBond(bondi)) { IAtom atomj = bondi.GetOther(atomi); if (checkAtom(atomj) && !reactant.GetConnectedSingleElectrons(atomj).Any()) { atomi.IsReactiveCenter = true; atomj.IsReactiveCenter = true; bondi.IsReactiveCenter = true; } } } } } }
private static void SetActiveCenters(IAtomContainer reactant, string atomSymbol, int charge) { foreach (var atomi in reactant.Atoms) { if (reactant.GetConnectedSingleElectrons(atomi).Count() == 1 && atomi.FormalCharge == charge) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.Order == BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if (atomj.FormalCharge == 0) { foreach (var bondj in reactant.GetConnectedBonds(atomj)) { if (bondj.Equals(bondi)) { continue; } if (bondj.Order == BondOrder.Single) { IAtom atomk = bondj.GetOther(atomj); if (atomk.Symbol.Equals(atomSymbol, StringComparison.Ordinal) && atomk.FormalCharge == 0) { atomi.IsReactiveCenter = true; atomj.IsReactiveCenter = true; atomk.IsReactiveCenter = true; bondi.IsReactiveCenter = true; bondj.IsReactiveCenter = true; } } } } } } } } }
public int CalculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container, bool throwExceptionForUnknowAtom) { return(this.CalculateNumberOfImplicitHydrogens(atom, container.GetBondOrderSum(atom), container.GetConnectedSingleElectrons(atom).Count(), container.GetConnectedBonds(atom), throwExceptionForUnknowAtom)); }
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> /// Reads atoms, bonds etc from atom container and converts to format /// InChI library requires, then places call for the library to generate /// the InChI. /// </summary> /// <param name="atomContainer">AtomContainer to generate InChI for.</param> /// <param name="ignore"></param> private void GenerateInChIFromCDKAtomContainer(IAtomContainer atomContainer, bool ignore) { this.ReferringAtomContainer = atomContainer; // Check for 3d coordinates bool all3d = true; bool all2d = true; foreach (var atom in atomContainer.Atoms) { if (all3d && atom.Point3D == null) { all3d = false; } if (all2d && atom.Point2D == null) { all2d = false; } } var atomMap = new Dictionary <IAtom, NInchiAtom>(); foreach (var atom in atomContainer.Atoms) { // Get coordinates // Use 3d if possible, otherwise 2d or none double x, y, z; if (all3d) { var p = atom.Point3D.Value; x = p.X; y = p.Y; z = p.Z; } else if (all2d) { var p = atom.Point2D.Value; x = p.X; y = p.Y; z = 0.0; } else { x = 0.0; y = 0.0; z = 0.0; } // Chemical element symbol var el = atom.Symbol; // Generate InChI atom var iatom = Input.Add(new NInchiAtom(x, y, z, el)); atomMap[atom] = iatom; // Check if charged var charge = atom.FormalCharge.Value; if (charge != 0) { iatom.Charge = charge; } // Check whether isotopic var isotopeNumber = atom.MassNumber; if (isotopeNumber != null) { iatom.IsotopicMass = isotopeNumber.Value; } // Check for implicit hydrogens // atom.HydrogenCount returns number of implicit hydrogens, not // total number // Ref: Posting to cdk-devel list by Egon Willighagen 2005-09-17 int?implicitH = atom.ImplicitHydrogenCount; // set implicit hydrogen count, -1 tells the inchi to determine it iatom.ImplicitH = implicitH ?? -1; // Check if radical int count = atomContainer.GetConnectedSingleElectrons(atom).Count(); if (count == 0) { // TODO - how to check whether singlet or undefined multiplicity } else if (count == 1) { iatom.Radical = INCHI_RADICAL.Doublet; } else if (count == 2) { iatom.Radical = INCHI_RADICAL.Triplet; } else { throw new CDKException("Unrecognised radical type"); } } // Process bonds var bondMap = new Dictionary <IBond, NInchiBond>(); foreach (var bond in atomContainer.Bonds) { // Assumes 2 centre bond var at0 = atomMap[bond.Begin]; var at1 = atomMap[bond.End]; // Get bond order INCHI_BOND_TYPE order; var bo = bond.Order; if (!ignore && bond.IsAromatic) { order = INCHI_BOND_TYPE.Altern; } else if (bo == BondOrder.Single) { order = INCHI_BOND_TYPE.Single; } else if (bo == BondOrder.Double) { order = INCHI_BOND_TYPE.Double; } else if (bo == BondOrder.Triple) { order = INCHI_BOND_TYPE.Triple; } else { throw new CDKException("Failed to generate InChI: Unsupported bond type"); } // Create InChI bond var ibond = new NInchiBond(at0, at1, order); bondMap[bond] = ibond; Input.Add(ibond); // Check for bond stereo definitions var stereo = bond.Stereo; // No stereo definition if (stereo == BondStereo.None) { ibond.BondStereo = INCHI_BOND_STEREO.None; } // Bond ending (fat end of wedge) below the plane else if (stereo == BondStereo.Down) { ibond.BondStereo = INCHI_BOND_STEREO.Single1Down; } // Bond ending (fat end of wedge) above the plane else if (stereo == BondStereo.Up) { ibond.BondStereo = INCHI_BOND_STEREO.Single1Up; } // Bond starting (pointy end of wedge) below the plane else if (stereo == BondStereo.DownInverted) { ibond.BondStereo = INCHI_BOND_STEREO.Single2Down; } // Bond starting (pointy end of wedge) above the plane else if (stereo == BondStereo.UpInverted) { ibond.BondStereo = INCHI_BOND_STEREO.Single2Up; } else if (stereo == BondStereo.EOrZ) { ibond.BondStereo = INCHI_BOND_STEREO.DoubleEither; } else if (stereo == BondStereo.UpOrDown) { ibond.BondStereo = INCHI_BOND_STEREO.Single1Either; } else if (stereo == BondStereo.UpOrDownInverted) { ibond.BondStereo = INCHI_BOND_STEREO.Single2Either; } // Bond with undefined stereochemistry else if (stereo == BondStereo.None) { if (order == INCHI_BOND_TYPE.Single) { ibond.BondStereo = INCHI_BOND_STEREO.Single1Either; } else if (order == INCHI_BOND_TYPE.Double) { ibond.BondStereo = INCHI_BOND_STEREO.DoubleEither; } } } // Process tetrahedral stereo elements foreach (var stereoElem in atomContainer.StereoElements) { if (stereoElem is ITetrahedralChirality chirality) { var stereoType = chirality.Stereo; var atC = atomMap[chirality.ChiralAtom]; var at0 = atomMap[chirality.Ligands[0]]; var at1 = atomMap[chirality.Ligands[1]]; var at2 = atomMap[chirality.Ligands[2]]; var at3 = atomMap[chirality.Ligands[3]]; var p = INCHI_PARITY.Unknown; if (stereoType == TetrahedralStereo.AntiClockwise) { p = INCHI_PARITY.Odd; } else if (stereoType == TetrahedralStereo.Clockwise) { p = INCHI_PARITY.Even; } else { throw new CDKException("Unknown tetrahedral chirality"); } var jniStereo = new NInchiStereo0D(atC, at0, at1, at2, at3, INCHI_STEREOTYPE.Tetrahedral, p); Input.Stereos.Add(jniStereo); } else if (stereoElem is IDoubleBondStereochemistry dbStereo) { var surroundingBonds = dbStereo.Bonds; if (surroundingBonds[0] == null || surroundingBonds[1] == null) { throw new CDKException("Cannot generate an InChI with incomplete double bond info"); } var stereoType = dbStereo.Stereo; IBond stereoBond = dbStereo.StereoBond; NInchiAtom at0 = null; NInchiAtom at1 = null; NInchiAtom at2 = null; NInchiAtom at3 = null; // TODO: I should check for two atom bonds... or maybe that should happen when you // create a double bond stereochemistry if (stereoBond.Contains(surroundingBonds[0].Begin)) { // first atom is A at1 = atomMap[surroundingBonds[0].Begin]; at0 = atomMap[surroundingBonds[0].End]; } else { // first atom is X at0 = atomMap[surroundingBonds[0].Begin]; at1 = atomMap[surroundingBonds[0].End]; } if (stereoBond.Contains(surroundingBonds[1].Begin)) { // first atom is B at2 = atomMap[surroundingBonds[1].Begin]; at3 = atomMap[surroundingBonds[1].End]; } else { // first atom is Y at2 = atomMap[surroundingBonds[1].End]; at3 = atomMap[surroundingBonds[1].Begin]; } var p = INCHI_PARITY.Unknown; if (stereoType == DoubleBondConformation.Together) { p = INCHI_PARITY.Odd; } else if (stereoType == DoubleBondConformation.Opposite) { p = INCHI_PARITY.Even; } else { throw new CDKException("Unknown double bond stereochemistry"); } var jniStereo = new NInchiStereo0D(null, at0, at1, at2, at3, INCHI_STEREOTYPE.DoubleBond, p); Input.Stereos.Add(jniStereo); } else if (stereoElem is ExtendedTetrahedral extendedTetrahedral) { TetrahedralStereo winding = extendedTetrahedral.Winding; // The peripherals (p<i>) and terminals (t<i>) are referring to // the following atoms. The focus (f) is also shown. // // p0 p2 // \ / // t0 = f = t1 // / \ // p1 p3 var terminals = extendedTetrahedral.FindTerminalAtoms(atomContainer); var peripherals = extendedTetrahedral.Peripherals.ToArray(); // InChI API is particular about the input, each terminal atom // needs to be present in the list of neighbors and they must // be at index 1 and 2 (i.e. in the middle). This is true even // of explicit atoms. For the implicit atoms, the terminals may // be in the peripherals already and so we correct the winding // and reposition as needed. var t0Bonds = OnlySingleBonded(atomContainer.GetConnectedBonds(terminals[0])); var t1Bonds = OnlySingleBonded(atomContainer.GetConnectedBonds(terminals[1])); // first if there are two explicit atoms we need to replace one // with the terminal atom - the configuration does not change if (t0Bonds.Count == 2) { var orgBond = t0Bonds[0]; t0Bonds.RemoveAt(0); var replace = orgBond.GetOther(terminals[0]); for (int i = 0; i < peripherals.Length; i++) { if (replace == peripherals[i]) { peripherals[i] = terminals[0]; } } } if (t1Bonds.Count == 2) { var orgBond = t0Bonds[0]; t1Bonds.RemoveAt(0); var replace = orgBond.GetOther(terminals[1]); for (int i = 0; i < peripherals.Length; i++) { if (replace == peripherals[i]) { peripherals[i] = terminals[1]; } } } // the neighbor attached to each terminal atom that we will // define the configuration of var t0Neighbor = t0Bonds[0].GetOther(terminals[0]); var t1Neighbor = t1Bonds[0].GetOther(terminals[1]); // we now need to move all the atoms into the correct positions // everytime we exchange atoms the configuration inverts for (int i = 0; i < peripherals.Length; i++) { if (i != 0 && t0Neighbor == peripherals[i]) { Swap(peripherals, i, 0); winding = winding.Invert(); } else if (i != 1 && terminals[0] == peripherals[i]) { Swap(peripherals, i, 1); winding = winding.Invert(); } else if (i != 2 && terminals[1] == peripherals[i]) { Swap(peripherals, i, 2); winding = winding.Invert(); } else if (i != 3 && t1Neighbor == peripherals[i]) { Swap(peripherals, i, 3); winding = winding.Invert(); } } var parity = INCHI_PARITY.Unknown; if (winding == TetrahedralStereo.AntiClockwise) { parity = INCHI_PARITY.Odd; } else if (winding == TetrahedralStereo.Clockwise) { parity = INCHI_PARITY.Even; } else { throw new CDKException("Unknown extended tetrahedral chirality"); } NInchiStereo0D jniStereo = new NInchiStereo0D(atomMap[extendedTetrahedral.Focus], atomMap[peripherals[0]], atomMap[peripherals[1]], atomMap[peripherals[2]], atomMap[peripherals[3]], INCHI_STEREOTYPE.Allene, parity); Input.Stereos.Add(jniStereo); } } try { Output = NInchiWrapper.GetInchi(Input); } catch (NInchiException jie) { throw new CDKException("Failed to generate InChI: " + jie.Message, jie); } }
/// <summary> /// Initiate process. /// It is needed to call the addExplicitHydrogensToSatisfyValency /// from the class tools.HydrogenAdder. /// </summary> /// <param name="reactants">reactants of the reaction.</param> /// <param name="agents">agents of the reaction (Must be in this case null).</param> /// <exception cref="CDKException"> Description of the Exception</exception> public IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents) { Debug.WriteLine("initiate reaction: SharingChargeDBReaction"); if (reactants.Count != 1) { throw new CDKException("SharingChargeDBReaction only expects one reactant"); } if (agents != null) { throw new CDKException("SharingChargeDBReaction don't expects agents"); } IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // if the parameter hasActiveCenter is not fixed yet, set the active centers var ipr = base.GetParameterClass(typeof(SetReactionCenter)); if (ipr != null && !ipr.IsSetParameter) { SetActiveCenters(reactant); } foreach (var atomi in reactant.Atoms) { if (atomi.IsReactiveCenter && atomi.FormalCharge == 1) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.IsReactiveCenter && bondi.Order != BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if (atomj.IsReactiveCenter && atomj.FormalCharge == 0) { if (!reactant.GetConnectedSingleElectrons(atomj).Any()) { var atomList = new List <IAtom> { atomj, atomi }; var bondList = new List <IBond> { bondi }; 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); }
internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, string atomSymbol, int charge) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // 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, atomSymbol, charge); } foreach (var atomi in reactants[0].Atoms) { if (atomi.IsReactiveCenter && reactant.GetConnectedSingleElectrons(atomi).Count() == 1 && atomi.FormalCharge == charge) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.IsReactiveCenter && bondi.Order == BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if (atomj.IsReactiveCenter && atomj.FormalCharge == 0) { foreach (var bondj in reactant.GetConnectedBonds(atomj)) { if (bondj.Equals(bondi)) { continue; } if (bondj.IsReactiveCenter && bondj.Order == BondOrder.Single) { IAtom atomk = bondj.GetOther(atomj); if (atomk.IsReactiveCenter && atomk.Symbol.Equals(atomSymbol, StringComparison.Ordinal) && atomk.FormalCharge == 0) { var atomList = new List <IAtom> { atomi, atomj, atomk }; var bondList = new List <IBond> { bondi, bondj }; IChemObjectSet <IAtomContainer> moleculeSet = reactant.Builder.NewChemObjectSet <IAtomContainer>(); moleculeSet.Add(reactant); IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, bondList); if (reaction == null) { continue; } else { setOfReactions.Add(reaction); } } } } } } } } } return(setOfReactions); }
/// <summary> /// Write the atoms of a molecule. We pass in the order of atoms since for compatibility we /// have shifted all hydrogens to the back. /// </summary> /// <param name="mol">molecule</param> /// <param name="atoms">the atoms of a molecule in desired output order</param> /// <param name="idxs">index lookup</param> /// <param name="atomToStereo">tetrahedral stereo lookup</param> /// <exception cref="IOException">low-level IO error</exception> /// <exception cref="CDKException">inconsistent state etc</exception> private void WriteAtomBlock(IAtomContainer mol, IAtom[] atoms, Dictionary <IChemObject, int> idxs, Dictionary <IAtom, ITetrahedralChirality> atomToStereo) { if (mol.Atoms.Count == 0) { return; } var dim = GetNumberOfDimensions(mol); writer.Write("BEGIN ATOM\n"); int atomIdx = 0; foreach (var atom in atoms) { var elem = NullAsZero(atom.AtomicNumber); var chg = NullAsZero(atom.FormalCharge); var mass = NullAsZero(atom.MassNumber); var hcnt = NullAsZero(atom.ImplicitHydrogenCount); var elec = mol.GetConnectedSingleElectrons(atom).Count(); int rad = 0; switch (elec) { case 1: // 2 rad = MDLV2000Writer.SpinMultiplicity.Monovalent.Value; break; case 2: // 1 or 3? Information loss as to which rad = MDLV2000Writer.SpinMultiplicity.DivalentSinglet.Value; break; } int expVal = 0; foreach (var bond in mol.GetConnectedBonds(atom)) { if (bond.Order == BondOrder.Unset) { throw new CDKException($"Unsupported bond order: {bond.Order}"); } expVal += bond.Order.Numeric(); } string symbol = GetSymbol(atom, elem); int rnum = -1; if (symbol[0] == 'R') { var matcher = R_GRP_NUM.Match(symbol); if (matcher.Success) { symbol = "R#"; rnum = int.Parse(matcher.Groups[1].Value, NumberFormatInfo.InvariantInfo); } } writer.Write(++atomIdx) .Write(' ') .Write(symbol) .Write(' '); var p2d = atom.Point2D; var p3d = atom.Point3D; switch (dim) { case 0: writer.Write("0 0 0 "); break; case 2: if (p2d != null) { writer.Write(p2d.Value.X).WriteDirect(' ') .Write(p2d.Value.Y).WriteDirect(' ') .Write("0 "); } else { writer.Write("0 0 0 "); } break; case 3: if (p3d != null) { writer.Write(p3d.Value.X).WriteDirect(' ') .Write(p3d.Value.Y).WriteDirect(' ') .Write(p3d.Value.Z).WriteDirect(' '); } else { writer.Write("0 0 0 "); } break; } writer.Write(NullAsZero(atom.GetProperty <int>(CDKPropertyName.AtomAtomMapping))); if (chg != 0 && chg >= -15 && chg <= 15) { writer.Write(" CHG=").Write(chg); } if (mass != 0) { writer.Write(" MASS=").Write(mass); } if (rad > 0 && rad < 4) { writer.Write(" RAD=").Write(rad); } if (rnum >= 0) { writer.Write(" RGROUPS=(1 ").Write(rnum).Write(")"); } // determine if we need to write the valence if (MDLValence.ImplicitValence(elem, chg, expVal) - expVal != hcnt) { int val = expVal + hcnt; if (val <= 0 || val > 14) { val = -1; // -1 is 0 } writer.Write(" VAL=").Write(val); } if (atomToStereo.TryGetValue(atom, out ITetrahedralChirality stereo)) { switch (GetLocalParity(idxs, stereo)) { case TetrahedralStereo.Clockwise: writer.Write(" CFG=1"); break; case TetrahedralStereo.AntiClockwise: writer.Write(" CFG=2"); break; default: break; } } writer.Write('\n'); } writer.Write("END ATOM\n"); }
/// <summary> /// Initiate process. /// It is needed to call the addExplicitHydrogensToSatisfyValency /// from the class tools.HydrogenAdder. /// </summary> /// <exception cref="CDKException"></exception> /// <param name="reactants">reactants of the reaction.</param> /// <param name="agents">agents of the reaction (Must be in this case null).</param> public IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents) { CheckInitiateParams(reactants, agents); IReactionSet setOfReactions = reactants.Builder.NewReactionSet(); IAtomContainer reactant = reactants[0]; // if the parameter hasActiveCenter is not fixed yet, set the active centers var ipr = base.GetParameterClass(typeof(SetReactionCenter)); if (ipr != null && !ipr.IsSetParameter) { SetActiveCenters(reactant); } foreach (var atomi in reactant.Atoms) { if (atomi.IsReactiveCenter && atomi.FormalCharge == 1) { foreach (var bondi in reactant.GetConnectedBonds(atomi)) { if (bondi.IsReactiveCenter && bondi.Order == BondOrder.Single) { IAtom atomj = bondi.GetOther(atomi); if (atomj.IsReactiveCenter && (atomj.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomj).Any()) { foreach (var bondj in reactant.GetConnectedBonds(atomj)) { if (bondj.Equals(bondi)) { continue; } if (bondj.IsReactiveCenter && bondj.Order == BondOrder.Single) { IAtom atomk = bondj.GetOther(atomj); if (atomk.IsReactiveCenter && (atomk.FormalCharge ?? 0) == 0 && !reactant.GetConnectedSingleElectrons(atomk).Any() && atomk.AtomicNumber.Equals(AtomicNumbers.H) ) { var atomList = new List <IAtom> { atomi, atomj, atomk }; var bondList = new List <IBond> { bondi, bondj }; 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); }