Пример #1
0
        /// <summary>
        /// <p>Converts a reaction to an 'inlined' reaction stored as a molecule. All
        /// reactants, agents, products are added to the molecule as disconnected
        /// components with atoms flagged as to their role <see cref="ReactionRole"/> and
        /// component group.</p>
        /// <p>
        /// The inlined reaction, stored in a molecule can be converted back to an explicit
        /// reaction with <see cref="ToReaction"/>. Data stored on the individual components (e.g.
        /// titles is lost in the conversion).
        /// </p>
        /// </summary>
        /// <param name="rxn">reaction to convert</param>
        /// <returns>inlined reaction stored in a molecule</returns>
        /// <seealso cref="ToReaction"/>
        public static IAtomContainer ToMolecule(IReaction rxn)
        {
            if (rxn == null)
            {
                throw new ArgumentNullException(nameof(rxn), "Null reaction provided");
            }
            IChemObjectBuilder bldr = rxn.Builder;
            IAtomContainer     mol  = bldr.NewAtomContainer();

            mol.SetProperties(rxn.GetProperties());
            mol.Id = rxn.Id;
            int grpId = 0;

            foreach (IAtomContainer comp in rxn.Reactants)
            {
                AssignRoleAndGrp(comp, ReactionRole.Reactant, ++grpId);
                mol.Add(comp);
            }
            foreach (IAtomContainer comp in rxn.Agents)
            {
                AssignRoleAndGrp(comp, ReactionRole.Agent, ++grpId);
                mol.Add(comp);
            }
            foreach (IAtomContainer comp in rxn.Products)
            {
                AssignRoleAndGrp(comp, ReactionRole.Product, ++grpId);
                mol.Add(comp);
            }
            return(mol);
        }
Пример #2
0
        /// <summary>
        /// Search and place branches of a chain or ring.
        /// </summary>
        /// <param name="chain">AtomContainer if atoms in an aliphatic chain or ring system</param>
        private void SearchAndPlaceBranches(IAtomContainer molecule, IAtomContainer chain, AtomPlacer3D ap3d,
                                            AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer)
        {
            //Debug.WriteLine("****** SEARCH AND PLACE ****** Chain length: "+chain.Atoms.Count);
            IAtomContainer branchAtoms    = molecule.Builder.NewAtomContainer();
            IAtomContainer connectedAtoms = molecule.Builder.NewAtomContainer();

            for (int i = 0; i < chain.Atoms.Count; i++)
            {
                var atoms = molecule.GetConnectedAtoms(chain.Atoms[i]);
                foreach (var atom in atoms)
                {
                    if (!atom.AtomicNumber.Equals(AtomicNumbers.H) & !atom.IsPlaced & !atom.IsInRing)
                    {
                        connectedAtoms.Add(ap3d.GetPlacedHeavyAtoms(molecule, chain.Atoms[i]));
                        try
                        {
                            SetBranchAtom(molecule, atom, chain.Atoms[i], connectedAtoms, ap3d, atlp3d);
                        }
                        catch (CDKException ex2)
                        {
                            Trace.TraceError($"SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms due to {ex2.ToString()}");
                            throw new CDKException($"SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms: {ex2.Message}", ex2);
                        }
                        branchAtoms.Atoms.Add(atom);
                        connectedAtoms.RemoveAllElements();
                    }
                }
            }//for ac.getAtomCount
            PlaceLinearChains3D(molecule, branchAtoms, ap3d, atlp3d, atomPlacer);
        }
Пример #3
0
        /// <summary>
        /// Add <paramref name="element"/> as <see cref="IAtom"/> to <paramref name="mol"/>.
        /// </summary>
        /// <param name="mol">The molecular to add atom.</param>
        /// <param name="element"><see cref="ChemicalElement"/> to add.</param>
        /// <returns><see cref="IAtom"/> added.</returns>
        public static IAtom Add(this IAtomContainer mol, ChemicalElement element)
        {
            var atom = mol.Builder.NewAtom(element);

            mol.Add(atom);
            return(atom);
        }
Пример #4
0
        public static IAtom AddAtom(this IAtomContainer mol, string elementSymbol)
        {
            var atom = mol.Builder.NewAtom(elementSymbol);

            mol.Add(atom);
            return(atom);
        }
Пример #5
0
        /// <summary>
        /// Puts all rings of a ringSet in a single atomContainer
        /// </summary>
        /// <param name="ringSet">The ringSet to use</param>
        /// <returns>The produced atomContainer</returns>
        public static IAtomContainer GetAllInOneContainer(IRingSet ringSet)
        {
            IAtomContainer resultContainer          = ringSet.Builder.NewAtomContainer();
            IEnumerator <IAtomContainer> containers = RingSetManipulator.GetAllAtomContainers(ringSet).GetEnumerator();

            while (containers.MoveNext())
            {
                resultContainer.Add(containers.Current);
            }
            return(resultContainer);
        }
Пример #6
0
 /// <summary>
 /// Utility method to add an <see cref="IChemObject"/> to an <see cref="IAtomContainer"/>.
 /// </summary>
 /// <param name="ac">the <see cref="IAtomContainer"/> to add to</param>
 /// <param name="item">the <see cref="IChemObject"/> to add</param>
 protected void AddToAtomContainer(IAtomContainer ac, IChemObject item)
 {
     if (item is IAtomContainer)
     {
         ac.Add((IAtomContainer)item);
     }
     else if (item is IAtom)
     {
         ac.Atoms.Add((IAtom)item);
     }
     else if (item is IBond)
     {
         ac.Bonds.Add((IBond)item);
     }
 }
Пример #7
0
        public IAtomContainer Read(IAtomContainer o)
        {
            IAtomContainer result = o;

            // do the actual parsing

            IGraph       model  = new Graph();
            TurtleParser parser = new TurtleParser();

            parser.Load(model, input);

            var            convertor = new Convertor(model);
            IAtomContainer mol       = convertor.Model2Molecule(o.Builder);

            result.Add(mol);
            return(result);
        }
Пример #8
0
        /// <summary>
        /// Positions the aliphatic substituents of a ring system
        /// </summary>
        /// <param name="rs">The RingSystem for which the substituents are to be laid out</param>
        /// <returns>A list of atoms that where laid out</returns>
        public IAtomContainer PlaceRingSubstituents(IRingSet rs, double bondLength)
        {
            Debug.WriteLine("RingPlacer.PlaceRingSubstituents() start");
            IRing          ring             = null;
            IAtom          atom             = null;
            IAtomContainer unplacedPartners = rs.Builder.NewAtomContainer();
            IAtomContainer sharedAtoms      = rs.Builder.NewAtomContainer();
            IAtomContainer primaryAtoms     = rs.Builder.NewAtomContainer();
            IAtomContainer treatedAtoms     = rs.Builder.NewAtomContainer();

            for (int j = 0; j < rs.Count; j++)
            {
                ring = (IRing)rs[j]; // Get the j-th Ring in RingSet rs
                for (int k = 0; k < ring.Atoms.Count; k++)
                {
                    unplacedPartners.RemoveAllElements();
                    sharedAtoms.RemoveAllElements();
                    primaryAtoms.RemoveAllElements();
                    atom = ring.Atoms[k];
                    var rings = rs.GetRings(atom);
                    var centerOfRingGravity = GeometryUtil.Get2DCenter(rings);
                    AtomPlacer.PartitionPartners(atom, unplacedPartners, sharedAtoms);
                    AtomPlacer.MarkNotPlaced(unplacedPartners);
                    try
                    {
                        for (int f = 0; f < unplacedPartners.Atoms.Count; f++)
                        {
                            Debug.WriteLine("placeRingSubstituents->unplacedPartners: "
                                            + (Molecule.Atoms.IndexOf(unplacedPartners.Atoms[f]) + 1));
                        }
                    }
                    catch (Exception)
                    {
                    }

                    treatedAtoms.Add(unplacedPartners);
                    if (unplacedPartners.Atoms.Count > 0)
                    {
                        AtomPlacer.DistributePartners(atom, sharedAtoms, centerOfRingGravity, unplacedPartners, bondLength);
                    }
                }
            }
            Debug.WriteLine("RingPlacer.PlaceRingSubstituents() end");
            return(treatedAtoms);
        }
Пример #9
0
        /// <summary>
        /// Layout all aliphatic chains with ZMatrix.
        /// </summary>
        /// <param name="startAtoms">AtomContainer of possible start atoms for a chain</param>
        private void PlaceLinearChains3D(IAtomContainer molecule, IAtomContainer startAtoms, AtomPlacer3D ap3d,
                                         AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer)
        {
            //Debug.WriteLine("****** PLACE LINEAR CHAINS ******");
            IAtom          dihPlacedAtom        = null;
            IAtom          thirdPlacedAtom      = null;
            IAtomContainer longestUnplacedChain = molecule.Builder.NewAtomContainer();

            if (startAtoms.Atoms.Count == 0)
            {
                //no branch points ->linear chain
                //Debug.WriteLine("------ LINEAR CHAIN - FINISH ------");
            }
            else
            {
                for (int i = 0; i < startAtoms.Atoms.Count; i++)
                {
                    //Debug.WriteLine("FOUND BRANCHED ALKAN");
                    //Debug.WriteLine("Atom NOT NULL:" + molecule.Atoms.IndexOf(startAtoms.GetAtomAt(i)));
                    thirdPlacedAtom = ap3d.GetPlacedHeavyAtom(molecule, startAtoms.Atoms[i]);
                    dihPlacedAtom   = ap3d.GetPlacedHeavyAtom(molecule, thirdPlacedAtom, startAtoms.Atoms[i]);
                    longestUnplacedChain.Atoms.Add(dihPlacedAtom);
                    longestUnplacedChain.Atoms.Add(thirdPlacedAtom);
                    longestUnplacedChain.Atoms.Add(startAtoms.Atoms[i]);
                    longestUnplacedChain.Add(AtomPlacer.GetLongestUnplacedChain(molecule, startAtoms.Atoms[i]));
                    SetAtomsToUnVisited(molecule);

                    if (longestUnplacedChain.Atoms.Count < 4)
                    {
                        //di,third,sec
                        //Debug.WriteLine("------ Single BRANCH METHYLTYP ------");
                        //break;
                    }
                    else
                    {
                        //Debug.WriteLine("LongestUnchainLength:"+longestUnplacedChain.Atoms.Count);
                        ap3d.PlaceAliphaticHeavyChain(molecule, longestUnplacedChain);
                        ap3d.ZMatrixChainToCartesian(molecule, true);
                        SearchAndPlaceBranches(molecule, longestUnplacedChain, ap3d, atlp3d, atomPlacer);
                    }
                    longestUnplacedChain.RemoveAllElements();
                }//for
            }
            //Debug.WriteLine("****** HANDLE ALIPHATICS END ******");
        }
Пример #10
0
        static bool JoinMmpFragments(
            IAtomContainer mol,
            string commonFragSmiles,
            int attachmentNo)
        {
            IAtomContainer cfMol = SmilesToAtomContainer(commonFragSmiles);

            //AtomContainerManipulator.removeHydrogens(cfMol);

            mol.Add(cfMol);

            List <IAtom> atoms = GetAttachmentAtoms(mol, attachmentNo);

            if (atoms.Count != 2)
            {
                return(false);
            }

            Bond b = new Bond(atoms[0], atoms[1], BondOrder.Single);

            mol.Bonds.Add(b);

            return(true);
        }
Пример #11
0
        public static void ExtractUniqueRingSystemsFromFile(string dataFile)
        {
            Console.Out.WriteLine("****** EXTRACT UNIQUE RING SYSTEMS ******");
            Console.Out.WriteLine($"From file: {dataFile}");

            Dictionary <string, string> hashRingSystems = new Dictionary <string, string>();
            SmilesGenerator             smilesGenerator = new SmilesGenerator();

            int            counterRings       = 0;
            int            counterMolecules   = 0;
            int            counterUniqueRings = 0;
            IRingSet       ringSet            = null;
            string         key = "";
            IAtomContainer ac  = null;

            string molfile = dataFile + "_UniqueRings";

            try
            {
                using (var fout = new FileStream(molfile, FileMode.Create))
                    using (var mdlw = new MDLV2000Writer(fout))
                    {
                        try
                        {
                            Console.Out.WriteLine("Start...");
                            using (var fin = new StreamReader(dataFile))
                                using (var imdl = new EnumerableSDFReader(fin, builder))
                                {
                                    Console.Out.WriteLine("Read File in..");

                                    foreach (var m in imdl)
                                    {
                                        counterMolecules = counterMolecules + 1;

                                        IRingSet ringSetM = Cycles.FindSSSR(m).ToRingSet();

                                        if (counterMolecules % 1000 == 0)
                                        {
                                            Console.Out.WriteLine("Molecules:" + counterMolecules);
                                        }

                                        if (ringSetM.Count > 0)
                                        {
                                            var ringSystems = RingPartitioner.PartitionRings(ringSetM);

                                            for (int i = 0; i < ringSystems.Count; i++)
                                            {
                                                ringSet = (IRingSet)ringSystems[i];
                                                ac      = builder.NewAtomContainer();
                                                var containers = RingSetManipulator.GetAllAtomContainers(ringSet);
                                                foreach (var container in containers)
                                                {
                                                    ac.Add(container);
                                                }
                                                counterRings = counterRings + 1;
                                                // Only connection is important
                                                for (int j = 0; j < ac.Atoms.Count; j++)
                                                {
                                                    (ac.Atoms[j]).Symbol = "C";
                                                }

                                                try
                                                {
                                                    key = smilesGenerator.Create(builder.NewAtomContainer(ac));
                                                }
                                                catch (CDKException e)
                                                {
                                                    Trace.TraceError(e.Message);
                                                    return;
                                                }

                                                if (hashRingSystems.ContainsKey(key))
                                                {
                                                }
                                                else
                                                {
                                                    counterUniqueRings = counterUniqueRings + 1; hashRingSystems[key] = "1";
                                                    try
                                                    {
                                                        mdlw.Write(builder.NewAtomContainer(ac));
                                                    }
                                                    catch (Exception emdl)
                                                    {
                                                        if (!(emdl is ArgumentException || emdl is CDKException))
                                                        {
                                                            throw;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                        }
                        catch (Exception exc)
                        {
                            Console.Out.WriteLine($"Could not read Molecules from file {dataFile} due to: {exc.Message}");
                        }
                    }
            }
            catch (Exception ex2)
            {
                Console.Out.WriteLine($"IOError:cannot write file due to: {ex2.ToString()}");
            }
            Console.Out.WriteLine($"READY Molecules:{counterMolecules} RingSystems:{counterRings} UniqueRingsSystem:{counterUniqueRings}");
            Console.Out.WriteLine($"HashtableKeys:{hashRingSystems.Count}");
        }
Пример #12
0
        /// <summary>
        /// Recursive function to produce valid configurations for <see cref="GetAllConfigurations"/>.
        /// </summary>
        private void FindConfigurationsRecursively(IReadOnlyList <int> rGroupNumbers, IReadOnlyList <IReadOnlyList <int> > occurrences,
                                                   IList <int> occurIndexes, List <int[]> distributions, List <IReadOnlyList <RGroup> > substitutes, int level,
                                                   IList <IAtomContainer> result)
        {
            if (level == rGroupNumbers.Count)
            {
                if (!CheckIfThenConditionsMet(rGroupNumbers, distributions))
                {
                    return;
                }

                // Clone the root to get a scaffold to plug the substitutes into.
                IAtomContainer root      = this.RootStructure;
                IAtomContainer rootClone = null;
                try
                {
                    rootClone = (IAtomContainer)root.Clone();
                }
                catch (Exception)
                {
                    //Abort with CDK exception
                    throw new CDKException("Clone() failed; could not perform R-group substitution.");
                }

                for (int rgpIdx = 0; rgpIdx < rGroupNumbers.Count; rgpIdx++)
                {
                    int rNum = rGroupNumbers[rgpIdx];
                    int pos  = 0;

                    var mapped = substitutes[rgpIdx];
                    foreach (var substitute in mapped)
                    {
                        IAtom rAtom = this.GetRgroupQueryAtoms(rNum)[pos];
                        if (substitute != null)
                        {
                            IAtomContainer rgrpClone = null;
                            try
                            {
                                rgrpClone = (IAtomContainer)(substitute.Group.Clone());
                            }
                            catch (Exception)
                            {
                                throw new CDKException("Clone() failed; could not perform R-group substitution.");
                            }

                            //root cloned, substitute cloned. These now need to be attached to each other..
                            rootClone.Add(rgrpClone);

                            if (this.RootAttachmentPoints.TryGetValue(rAtom, out IReadOnlyDictionary <int, IBond> rAttachmentPoints))
                            {
                                // Loop over attachment points of the R# atom
                                for (int apo = 0; apo < rAttachmentPoints.Count; apo++)
                                {
                                    IBond bond = rAttachmentPoints[apo + 1];
                                    //Check how R# is attached to bond
                                    int whichAtomInBond = 0;
                                    if (bond.End.Equals(rAtom))
                                    {
                                        whichAtomInBond = 1;
                                    }
                                    IAtom subsAt = null;
                                    if (apo == 0)
                                    {
                                        subsAt = substitute.FirstAttachmentPoint;
                                    }
                                    else
                                    {
                                        subsAt = substitute.SecondAttachmentPoint;
                                    }

                                    //Do substitution with the clones
                                    IBond cloneBond = rootClone.Bonds[GetBondPosition(bond, root)];
                                    if (subsAt != null)
                                    {
                                        IAtom subsCloneAtom = rgrpClone.Atoms[GetAtomPosition(subsAt,
                                                                                              substitute.Group)];
                                        cloneBond.Atoms[whichAtomInBond] = subsCloneAtom;
                                    }
                                }
                            }

                            //Optional: shift substitutes 2D for easier visual checking
                            if (rAtom.Point2D != null && substitute != null &&
                                substitute.FirstAttachmentPoint != null &&
                                substitute.FirstAttachmentPoint.Point2D != null)
                            {
                                Vector2 pointR = rAtom.Point2D.Value;
                                Vector2 pointC = substitute.FirstAttachmentPoint.Point2D.Value;
                                double  xDiff  = pointC.X - pointR.X;
                                double  yDiff  = pointC.Y - pointR.Y;
                                foreach (var subAt in rgrpClone.Atoms)
                                {
                                    if (subAt.Point2D != null)
                                    {
                                        subAt.Point2D = new Vector2((subAt.Point2D.Value.X - xDiff), (subAt.Point2D.Value.Y - yDiff));
                                    }
                                }
                            }
                        }
                        else
                        {
                            //Distribution flag is 0, this means the R# group will not be substituted.
                            //Any atom connected to this group should be given the defined IsRestH value.
                            IAtom discarded = rootClone.Atoms[GetAtomPosition(rAtom, root)];
                            foreach (var r0Bond in rootClone.Bonds)
                            {
                                if (r0Bond.Contains(discarded))
                                {
                                    foreach (var atInBond in r0Bond.Atoms)
                                    {
                                        atInBond.SetProperty(CDKPropertyName.RestH, this.RGroupDefinitions[rNum]
                                                             .IsRestH);
                                    }
                                }
                            }
                        }

                        pos++;
                    }
                }

                //Remove R# remnants from the clone, bonds and atoms that may linger.
                bool confHasRGroupBonds = true;
                while (confHasRGroupBonds)
                {
                    foreach (var cloneBond in rootClone.Bonds)
                    {
                        bool removeBond = false;
                        if (cloneBond.Begin is IPseudoAtom &&
                            IsValidRgroupQueryLabel(((IPseudoAtom)cloneBond.Begin).Label))
                        {
                            removeBond = true;
                        }
                        else if (cloneBond.End is IPseudoAtom &&
                                 IsValidRgroupQueryLabel(((IPseudoAtom)cloneBond.End).Label))
                        {
                            removeBond = true;
                        }

                        if (removeBond)
                        {
                            rootClone.Bonds.Remove(cloneBond);
                            confHasRGroupBonds = true;
                            break;
                        }
                        confHasRGroupBonds = false;
                    }
                }
                bool confHasRGroupAtoms = true;
                while (confHasRGroupAtoms)
                {
                    foreach (var cloneAt in rootClone.Atoms)
                    {
                        if (cloneAt is IPseudoAtom)
                        {
                            if (IsValidRgroupQueryLabel(((IPseudoAtom)cloneAt).Label))
                            {
                                rootClone.Atoms.Remove(cloneAt);
                                confHasRGroupAtoms = true;
                                break;
                            }
                        }
                        confHasRGroupAtoms = false;
                    }
                }
                //Add to result list
                result.Add(rootClone);
            }
            else
            {
                for (int idx = 0; idx < occurrences[level].Count; idx++)
                {
                    occurIndexes[level] = idx;
                    //With an occurrence picked 0..n for this level's R-group, now find
                    //all possible distributions (positional alternatives).
                    int   occurrence = occurrences[level][idx];
                    int   positions  = this.GetRgroupQueryAtoms(rGroupNumbers[level]).Count;
                    int[] candidate  = new int[positions];
                    for (int j = 0; j < candidate.Length; j++)
                    {
                        candidate[j] = 0;
                    }
                    var rgrpDistributions = new List <int[]>();
                    FindDistributions(occurrence, candidate, rgrpDistributions, 0);

                    foreach (var distribution in rgrpDistributions)
                    {
                        distributions[level] = distribution;

                        var mapping           = new RGroup[distribution.Length];
                        var mappedSubstitutes = new List <List <RGroup> >();
                        MapSubstitutes(this.RGroupDefinitions[rGroupNumbers[level]], 0, distribution, mapping, mappedSubstitutes);

                        foreach (var mappings in mappedSubstitutes)
                        {
                            substitutes[level] = mappings;
                            FindConfigurationsRecursively(rGroupNumbers, occurrences, occurIndexes, distributions, substitutes, level + 1, result);
                        }
                    }
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Read a Reaction from a file in MDL RXN format
        /// </summary>
        /// <returns>The Reaction that was read from the MDL file.</returns>
        private IReaction ReadReaction(IChemObjectBuilder builder)
        {
            IReaction reaction = builder.NewReaction();

            try
            {
                input.ReadLine(); // first line should be $RXN
                input.ReadLine(); // second line
                input.ReadLine(); // third line
                input.ReadLine(); // fourth line
            }
            catch (IOException exception)
            {
                Debug.WriteLine(exception);
                throw new CDKException("Error while reading header of RXN file", exception);
            }

            int reactantCount = 0;
            int productCount  = 0;
            int agentCount    = 0;

            try
            {
                string countsLine = input.ReadLine();

                // this line contains the number of reactants and products
                var tokenizer = Strings.Tokenize(countsLine).GetEnumerator();
                tokenizer.MoveNext();
                reactantCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);
                Trace.TraceInformation("Expecting " + reactantCount + " reactants in file");
                tokenizer.MoveNext();
                productCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);

                if (tokenizer.MoveNext())
                {
                    agentCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);
                    // ChemAxon extension, technically BIOVIA now support this but
                    // not documented yet
                    if (ReaderMode == ChemObjectReaderMode.Strict && agentCount > 0)
                    {
                        throw new CDKException("RXN files uses agent count extension");
                    }
                }
                Trace.TraceInformation("Expecting " + productCount + " products in file");
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is FormatException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while counts line of RXN file", exception);
                }
                throw;
            }

            // now read the reactants
            try
            {
                for (int i = 1; i <= reactantCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // announceMDLFileLine
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    // Changed this to mdlv2000 reader
                    MDLV2000Reader reader   = new MDLV2000Reader(new StringReader(molFile.ToString()), base.ReaderMode);
                    IAtomContainer reactant = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Reactants.Add(reactant);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading products", exception);
                }
                throw;
            }

            // now read the products
            try
            {
                for (int i = 1; i <= agentCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // String announceMDLFileLine =
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    MDLV2000Reader reader  = new MDLV2000Reader(new StringReader(molFile.ToString()));
                    IAtomContainer product = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Agents.Add(product);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading reactant", exception);
                }
                throw;
            }

            // now read the products
            try
            {
                for (int i = 1; i <= productCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // string announceMDLFileLine =
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    MDLV2000Reader reader  = new MDLV2000Reader(new StringReader(molFile.ToString()));
                    IAtomContainer product = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Products.Add(product);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading products", exception);
                }
                throw;
            }

            // now try to map things, if wanted
            Trace.TraceInformation("Reading atom-atom mapping from file");
            // distribute all atoms over two AtomContainer's
            IAtomContainer reactingSide = builder.NewAtomContainer();

            foreach (var molecule in reaction.Reactants)
            {
                reactingSide.Add(molecule);
            }
            IAtomContainer producedSide = builder.NewAtomContainer();

            foreach (var molecule in reaction.Products)
            {
                producedSide.Add(molecule);
            }

            // map the atoms
            int mappingCount = 0;

            //        IAtom[] reactantAtoms = reactingSide.GetAtoms();
            //        IAtom[] producedAtoms = producedSide.GetAtoms();
            for (int i = 0; i < reactingSide.Atoms.Count; i++)
            {
                for (int j = 0; j < producedSide.Atoms.Count; j++)
                {
                    IAtom eductAtom   = reactingSide.Atoms[i];
                    IAtom productAtom = producedSide.Atoms[j];
                    if (eductAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping) != null &&
                        eductAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping).Equals(
                            productAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping)))
                    {
                        reaction.Mappings.Add(builder.NewMapping(eductAtom, productAtom));
                        mappingCount++;
                        break;
                    }
                }
            }
            Trace.TraceInformation("Mapped atom pairs: " + mappingCount);

            return(reaction);
        }
Пример #14
0
        private TestResults TestFile(string dir, string filename, Type readerType)
        {
            var            matcher = CDK.AtomTypeMatcher;
            var            ins     = ResourceLoader.GetAsStream(dir + filename);
            var            reader  = (ISimpleChemObjectReader)readerType.GetConstructor(new Type[] { typeof(Stream) }).Invoke(new object[] { ins });
            IAtomContainer mol     = null;

            if (reader.Accepts(typeof(IAtomContainer)))
            {
                mol = reader.Read(new Silent.AtomContainer());
            }
            else if (reader.Accepts(typeof(IChemFile)))
            {
                var chemFile = reader.Read(builder.NewChemFile());
                mol = builder.NewAtomContainer();
                var containers = ChemFileManipulator.GetAllAtomContainers(chemFile);
                foreach (var container in containers)
                {
                    mol.Add(container);
                }
            }

            Assert.IsNotNull(mol, "Could not read the file into a IAtomContainer: " + filename);

            TestResults results = new TestResults();

            Trace.Assert(mol != null);
            foreach (var atom in mol.Atoms)
            {
                results.tested++;
                IAtomType matched = matcher.FindMatchingAtomType(mol, atom);
                if (matched == null)
                {
                    results.failed++;
                    Console.Out.WriteLine("Could not match atom: " + results.tested + " in file " + filename);
                }
                else
                // OK, the matcher did find something. Now, let's see of the
                // atom type properties are consistent with those of the atom
                if (!atom.Symbol.Equals(matched.Symbol))
                {
                    // OK, OK, that's very basic indeed, but why not
                    results.failed++;
                    Console.Out.WriteLine("Symbol does not match: " + results.tested + " in file " + filename);
                    Console.Out.WriteLine("Found: " + atom.Symbol + ", expected: " + matched.Symbol);
                }
                else if (!atom.Hybridization.IsUnset() &&
                         atom.Hybridization != matched.Hybridization)
                {
                    results.failed++;
                    Console.Out.WriteLine("Hybridization does not match: " + results.tested + " in file " + filename);
                    Console.Out.WriteLine("Found: " + atom.Hybridization + ", expected: " + matched.Hybridization
                                          + " (" + matched.AtomTypeName + ")");
                }
                else if (atom.FormalCharge.Value != matched.FormalCharge.Value)
                {
                    results.failed++;
                    Console.Out.WriteLine("Formal charge does not match: " + results.tested + " in file " + filename);
                    Console.Out.WriteLine("Found: " + atom.FormalCharge + ", expected: " + matched.FormalCharge
                                          + " (" + matched.AtomTypeName + ")");
                }
                else
                {
                    var connections     = mol.GetConnectedBonds(atom);
                    int connectionCount = connections.Count();
                    //                int piBondsFound = (int)mol.GetBondOrderSum(atom) - connectionCount;
                    // there might be missing hydrogens, so: found <= expected
                    if (matched.FormalNeighbourCount != null &&
                        connectionCount > matched.FormalNeighbourCount &&
                        !"X".Equals(matched.AtomTypeName))
                    {
                        results.failed++;
                        Console.Out.WriteLine("Number of neighbors is too high: " + results.tested + " in file " + filename);
                        Console.Out.WriteLine("Found: " + connectionCount + ", expected (max): "
                                              + matched.FormalNeighbourCount + " (" + matched.AtomTypeName + ")");
                    }
                    // there might be missing double bonds, so: found <= expected
                    //                if (piBondsFound > matched.GetXXXX()) {
                    //                    results.failed++;
                    //                    Console.Out.WriteLine("Number of neighbors is too high: " + results.tested + " in file " + filename);
                    //                    Console.Out.WriteLine("Found: " + atom.FormalNeighbourCount +
                    //                                       ", expected (max): " + matched.FormalNeighbourCount);
                    //                }
                }
            }
            return(results);
        }