public object Visit(ASTReaction node, object data) { IAtomContainer query = new QueryAtomContainer(builder); for (int grpIdx = 0; grpIdx < node.JjtGetNumChildren(); grpIdx++) { int rollback = query.Atoms.Count; ASTGroup group = (ASTGroup)node.JjtGetChild(grpIdx); group.JjtAccept(this, query); // fill in the roles for newly create atoms if (group.Role != ReactionRoles.Any) { IQueryAtom roleQueryAtom = null; ReactionRole?role = null; // use single instances switch (group.Role) { case ReactionRoles.Reactant: roleQueryAtom = ReactionRoleQueryAtom.RoleReactant; role = ReactionRole.Reactant; break; case ReactionRoles.Agent: roleQueryAtom = ReactionRoleQueryAtom.RoleAgent; role = ReactionRole.Agent; break; case ReactionRoles.Product: roleQueryAtom = ReactionRoleQueryAtom.RoleProduct; role = ReactionRole.Product; break; } if (roleQueryAtom != null) { while (rollback < query.Atoms.Count) { IAtom org = query.Atoms[rollback]; IAtom rep = LogicalOperatorAtom.And(roleQueryAtom, (IQueryAtom)org); // ensure AAM is propagated rep.SetProperty(CDKPropertyName.AtomAtomMapping, org.GetProperty <int?>(CDKPropertyName.AtomAtomMapping)); rep.SetProperty(CDKPropertyName.ReactionRole, role); AtomContainerManipulator.ReplaceAtomByAtom(query, org, rep); rollback++; } } } } return(query); }
static void Main() { { IAtomContainer container = null; IAtom atom1 = null; IAtom atom2 = null; #region 1 AtomContainerManipulator.ReplaceAtomByAtom(container, atom1, atom2); #endregion } #region SetSingleOrDoubleFlags SmilesParser parser = new SmilesParser(ChemObjectBuilder.Instance, false); IAtomContainer biphenyl = parser.ParseSmiles("c1cccc(c1)c1ccccc1"); AtomContainerManipulator.SetSingleOrDoubleFlags(biphenyl); #endregion }
/// <summary> /// Transfers the CXSMILES state onto the CDK atom/molecule data-structures. /// </summary> /// <param name="bldr">chem-object builder</param> /// <param name="atoms">atoms parsed from the molecule or reaction. Reaction molecules are list left to right.</param> /// <param name="atomToMol">look-up of atoms to molecules when connectivity/sgroups need modification</param> /// <param name="cxstate">the CXSMILES state to read from</param> private void AssignCxSmilesInfo(IChemObjectBuilder bldr, IChemObject chemObj, List <IAtom> atoms, Dictionary <IAtom, IAtomContainer> atomToMol, CxSmilesState cxstate) { // atom-labels - must be done first as we replace atoms if (cxstate.atomLabels != null) { foreach (var e in cxstate.atomLabels) { // bounds check if (e.Key >= atoms.Count) { continue; } var old = atoms[e.Key]; var pseudo = bldr.NewPseudoAtom(); var val = e.Value; // specialised label handling if (val.EndsWith("_p", StringComparison.Ordinal)) // pseudo label { val = val.Substring(0, val.Length - 2); } else if (val.StartsWith("_AP", StringComparison.Ordinal)) // attachment point { pseudo.AttachPointNum = ParseIntSafe(val.Substring(3)); } pseudo.Label = val; pseudo.AtomicNumber = 0; pseudo.ImplicitHydrogenCount = 0; var mol = atomToMol[old]; AtomContainerManipulator.ReplaceAtomByAtom(mol, old, pseudo); atomToMol.Add(pseudo, mol); atoms[e.Key] = pseudo; } } // atom-values - set as comment, mirrors Molfile reading behavior if (cxstate.atomValues != null) { foreach (var e in cxstate.atomValues) { atoms[e.Key].SetProperty(CDKPropertyName.Comment, e.Value); } } // atom-coordinates if (cxstate.atomCoords != null) { var numAtoms = atoms.Count; var numCoords = cxstate.atomCoords.Count; var lim = Math.Min(numAtoms, numCoords); if (cxstate.coordFlag) { for (int i = 0; i < lim; i++) { atoms[i].Point3D = new Vector3( cxstate.atomCoords[i][0], cxstate.atomCoords[i][1], cxstate.atomCoords[i][2]); } } else { for (int i = 0; i < lim; i++) { atoms[i].Point2D = new Vector2( cxstate.atomCoords[i][0], cxstate.atomCoords[i][1]); } } } // atom radicals if (cxstate.atomRads != null) { foreach (var e in cxstate.atomRads) { // bounds check if (e.Key >= atoms.Count) { continue; } int count = 0; var aa = e.Value; switch (e.Value) { case CxSmilesState.Radical.Monovalent: count = 1; break; // no distinction in CDK between singled/triplet case CxSmilesState.Radical.Divalent: case CxSmilesState.Radical.DivalentSinglet: case CxSmilesState.Radical.DivalentTriplet: count = 2; break; // no distinction in CDK between doublet/quartet case CxSmilesState.Radical.Trivalent: case CxSmilesState.Radical.TrivalentDoublet: case CxSmilesState.Radical.TrivalentQuartet: count = 3; break; } var atom = atoms[e.Key]; var mol = atomToMol[atom]; while (count-- > 0) { mol.SingleElectrons.Add(bldr.NewSingleElectron(atom)); } } } var sgroupMap = new MultiDictionary <IAtomContainer, Sgroup>(); // positional-variation if (cxstate.positionVar != null) { foreach (var e in cxstate.positionVar) { var sgroup = new Sgroup { Type = SgroupType.ExtMulticenter }; var beg = atoms[e.Key]; var mol = atomToMol[beg]; var bonds = mol.GetConnectedBonds(beg); if (bonds.Count() == 0) { continue; // bad } sgroup.Add(beg); sgroup.Add(bonds.First()); foreach (var endpt in e.Value) { sgroup.Add(atoms[endpt]); } sgroupMap.Add(mol, sgroup); } } // data sgroups if (cxstate.dataSgroups != null) { foreach (var dsgroup in cxstate.dataSgroups) { if (dsgroup.Field != null && dsgroup.Field.StartsWith("cdk:", StringComparison.Ordinal)) { chemObj.SetProperty(dsgroup.Field, dsgroup.Value); } } } // polymer Sgroups if (cxstate.sgroups != null) { foreach (var psgroup in cxstate.sgroups) { var sgroup = new Sgroup(); var atomset = new HashSet <IAtom>(); IAtomContainer mol = null; foreach (var idx in psgroup.AtomSet) { if (idx >= atoms.Count) { continue; } var atom = atoms[idx]; var amol = atomToMol[atom]; if (mol == null) { mol = amol; } else if (amol != mol) { goto C_PolySgroup; } atomset.Add(atom); } if (mol == null) { continue; } foreach (var atom in atomset) { foreach (var bond in mol.GetConnectedBonds(atom)) { if (!atomset.Contains(bond.GetOther(atom))) { sgroup.Add(bond); } } sgroup.Add(atom); } sgroup.Subscript = psgroup.Subscript; sgroup.PutValue(SgroupKey.CtabConnectivity, psgroup.Supscript); switch (psgroup.Type) { case "n": sgroup.Type = SgroupType.CtabStructureRepeatUnit; break; case "mon": sgroup.Type = SgroupType.CtabMonomer; break; case "mer": sgroup.Type = SgroupType.CtabMer; break; case "co": sgroup.Type = SgroupType.CtabCopolymer; break; case "xl": sgroup.Type = SgroupType.CtabCrossLink; break; case "mod": sgroup.Type = SgroupType.CtabModified; break; case "mix": sgroup.Type = SgroupType.CtabMixture; break; case "f": sgroup.Type = SgroupType.CtabFormulation; break; case "any": sgroup.Type = SgroupType.CtabAnyPolymer; break; case "gen": sgroup.Type = SgroupType.CtabGeneric; break; case "c": sgroup.Type = SgroupType.CtabComponent; break; case "grf": sgroup.Type = SgroupType.CtabGraft; break; case "alt": sgroup.Type = SgroupType.CtabCopolymer; sgroup.PutValue(SgroupKey.CtabSubType, "ALT"); break; case "ran": sgroup.Type = SgroupType.CtabCopolymer; sgroup.PutValue(SgroupKey.CtabSubType, "RAN"); break; case "blk": sgroup.Type = SgroupType.CtabCopolymer; sgroup.PutValue(SgroupKey.CtabSubType, "BLO"); break; } sgroupMap.Add(mol, sgroup); C_PolySgroup: ; } } // assign Sgroups foreach (var e in sgroupMap) { e.Key.SetCtabSgroups(new List <Sgroup>(e.Value)); } }
/// <summary> /// Reads labels. /// </summary> public void ReadSgroup(IAtomContainer readData) { bool foundEND = false; while (!foundEND) { string command = ReadCommand(ReadLine()); if (string.Equals("END SGROUP", command, StringComparison.Ordinal)) { foundEND = true; } else { Debug.WriteLine($"Parsing Sgroup line: {command}"); var tokenizer = Strings.Tokenize(command).GetEnumerator(); // parse the index tokenizer.MoveNext(); string indexString = tokenizer.Current; Trace.TraceWarning("Skipping external index: " + indexString); // parse command type tokenizer.MoveNext(); string type = tokenizer.Current; // parse the external index tokenizer.MoveNext(); string externalIndexString = tokenizer.Current; Trace.TraceWarning("Skipping external index: " + externalIndexString); // the rest are key=value fields var options = new Dictionary <string, string>(); if (command.IndexOf('=') != -1) { options = ParseOptions(ExhaustStringTokenizer(tokenizer)); } // now interpret line if (type.StartsWith("SUP", StringComparison.Ordinal)) { var keys = options.Keys; int atomID = -1; string label = ""; foreach (var key in keys) { string value = options[key]; try { if (string.Equals(key, "ATOMS", StringComparison.Ordinal)) { var atomsTokenizer = Strings.Tokenize(value).GetEnumerator(); atomsTokenizer.MoveNext(); int.Parse(atomsTokenizer.Current, NumberFormatInfo.InvariantInfo); // should be 1, int atomCount = atomsTokenizer.MoveNext(); atomID = int.Parse(atomsTokenizer.Current, NumberFormatInfo.InvariantInfo); } else if (string.Equals(key, "LABEL", StringComparison.Ordinal)) { label = value; } else { Trace.TraceWarning("Not parsing key: " + key); } } catch (Exception exception) { string error = "Error while parsing key/value " + key + "=" + value + ": " + exception.Message; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } if (atomID != -1 && label.Length > 0) { IAtom original = readData.Atoms[atomID - 1]; IAtom replacement = original; if (!(original is IPseudoAtom)) { replacement = readData.Builder.NewPseudoAtom(original); } ((IPseudoAtom)replacement).Label = label; if (replacement != original) { AtomContainerManipulator.ReplaceAtomByAtom(readData, original, replacement); } } } } else { Trace.TraceWarning("Skipping unrecognized SGROUP type: " + type); } } } }