/// <summary>
        /// Extract the AtomEncoders using reflection
        ///
        /// <param name="generator">/// @return</param>
        /// </summary>
        public static IList <IAtomEncoder> GetEncoders(IAtomHashGenerator generator)
        {
            var field = generator.GetType().GetField("seedGenerator", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            if (field == null)
            {
                Console.Error.WriteLine("Field 'seedGenerator' is not found.");
                goto Exit;
            }
            object o1 = field.GetValue(generator);

            if (o1 is SeedGenerator)
            {
                SeedGenerator seedGenerator = (SeedGenerator)o1;
                var           f2            = seedGenerator.GetType().GetField("encoder", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                if (f2 == null)
                {
                    Console.Error.WriteLine("Field 'encoder' is not found.");
                    goto Exit;
                }
                object o2 = f2.GetValue(seedGenerator);
                return(GetEncoders((ConjugatedAtomEncoder)o2));
            }
Exit:
            return(new List <IAtomEncoder>());
        }
Example #2
0
 /// <summary>
 /// Create a perturbed hash generator using the provided seed generator to
 /// initialise atom invariants and using the provided stereo factory.
 /// </summary>
 /// <param name="seeds"></param>
 /// <param name="simple">generator to encode the initial values of atoms</param>
 /// <param name="pseudorandom">pseudorandom number generator used to randomise hash distribution</param>
 /// <param name="factory">a stereo encoder factory</param>
 /// <param name="finder">equivalent set finder for driving the systematic perturbation</param>
 /// <param name="suppression">suppression of atoms (these atoms are 'ignored' in the hash generation)</param>
 /// <exception cref="ArgumentException">depth was less then 0</exception>
 /// <exception cref="ArgumentNullException">    seed generator or pseudo random was null</exception>
 /// <seealso cref="SeedGenerator"/>
 public PerturbedAtomHashGenerator(SeedGenerator seeds, AbstractAtomHashGenerator simple, Pseudorandom pseudorandom,
                                   IStereoEncoderFactory factory, EquivalentSetFinder finder, AtomSuppression suppression)
     : base(pseudorandom)
 {
     this.finder      = finder;
     this.factory     = factory;
     this.simple      = simple ?? throw new ArgumentNullException(nameof(simple), "no simple generator provided");
     this.seeds       = seeds ?? throw new ArgumentNullException(nameof(seeds), "no seed generator provided");
     this.suppression = suppression ?? throw new ArgumentNullException(nameof(suppression), "no suppression provided, use AtomSuppression.None()");
 }
        public void TestGenerate()
        {
            IAtomContainer m1 = Cyclopentylcyclopentane();
            IAtomContainer m2 = Decahydronaphthalene();

            SeedGenerator seeding      = new SeedGenerator(BasicAtomEncoder.AtomicNumber);
            Pseudorandom  pseudorandom = new Xorshift();

            IMoleculeHashGenerator basic   = new BasicMoleculeHashGenerator(new BasicAtomHashGenerator(seeding, pseudorandom, 8));
            IMoleculeHashGenerator perturb = new BasicMoleculeHashGenerator(new PerturbedAtomHashGenerator(seeding,
                                                                                                           new BasicAtomHashGenerator(seeding, pseudorandom, 8), pseudorandom, StereoEncoderFactory.Empty,
                                                                                                           new MinimumEquivalentCyclicSet(), AtomSuppression.Unsuppressed));

            // basic encoding should say these are the same
            Assert.AreEqual(basic.Generate(m1), basic.Generate(m2));

            // perturbed encoding should differentiate them
            Assert.AreNotEqual(perturb.Generate(m1), perturb.Generate(m2));
        }
Example #4
0
        public void TestGenerate()
        {
            var m_container = new Mock <IAtomContainer>(); var container = m_container.Object;

            var           m_encoder = new Mock <IAtomEncoder>(); var encoder = m_encoder.Object;
            SeedGenerator generator = new SeedGenerator(encoder);

            var m_c1 = new Mock <IAtom>(); var c1 = m_c1.Object;
            var m_c2 = new Mock <IAtom>(); var c2 = m_c2.Object;
            var m_c3 = new Mock <IAtom>(); var c3 = m_c3.Object;
            var m_c4 = new Mock <IAtom>(); var c4 = m_c4.Object;
            var m_c5 = new Mock <IAtom>(); var c5 = m_c5.Object;

            m_container.SetupGet(n => n.Atoms.Count).Returns(5);
            m_container.SetupGet(n => n.Atoms[0]).Returns(c1);
            m_container.SetupGet(n => n.Atoms[1]).Returns(c2);
            m_container.SetupGet(n => n.Atoms[2]).Returns(c3);
            m_container.SetupGet(n => n.Atoms[3]).Returns(c4);
            m_container.SetupGet(n => n.Atoms[4]).Returns(c5);

            m_encoder.Setup(n => n.Encode(c1, container)).Returns(42);
            m_encoder.Setup(n => n.Encode(c2, container)).Returns(42);
            m_encoder.Setup(n => n.Encode(c3, container)).Returns(42);
            m_encoder.Setup(n => n.Encode(c4, container)).Returns(42);
            m_encoder.Setup(n => n.Encode(c5, container)).Returns(42);

            generator.Generate(container);

            m_container.Verify(n => n.Atoms.Count, Times.Exactly(1));

            m_container.Verify(n => n.Atoms[It.IsAny <int>()], Times.Exactly(5));

            m_encoder.Verify(n => n.Encode(c1, container), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c2, container), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c3, container), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c4, container), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c5, container), Times.Exactly(1));

            //VerifyNoMoreInteractions(c1, c2, c3, c4, c5, container, encoder);
        }
Example #5
0
        /// <summary>
        /// Given the current configuration create an <see cref="IAtomHashGenerator"/>.
        /// </summary>
        /// <returns>instance of the generator</returns>
        /// <exception cref="ArgumentException">no depth or encoders were configured</exception>
        public IAtomHashGenerator Atomic()
        {
            if (depth < 0)
            {
                throw new ArgumentException("no depth specified, use .Depth(int)");
            }

            List <IAtomEncoder> encoders = new List <IAtomEncoder>();

            // set is ordered
            encoders.AddRange(encoderSet);
            encoders.AddRange(this.customEncoders);

            // check if suppression of atoms is wanted - if not use a default value
            // we also use the 'Basic' generator (see below)
            bool suppress = suppression != AtomSuppression.Unsuppressed;

            IAtomEncoder  encoder = new ConjugatedAtomEncoder(encoders);
            SeedGenerator seeds   = new SeedGenerator(encoder, suppression);

            AbstractAtomHashGenerator simple = suppress ? (AbstractAtomHashGenerator) new SuppressedAtomHashGenerator(seeds, new Xorshift(),
                                                                                                                      MakeStereoEncoderFactory(), suppression, depth) : (AbstractAtomHashGenerator) new BasicAtomHashGenerator(seeds, new Xorshift(),
                                                                                                                                                                                                                               MakeStereoEncoderFactory(), depth);

            // if there is a finder for checking equivalent vertices then the user
            // wants to 'perturb' the hashed
            if (equivSetFinder != null)
            {
                return(new PerturbedAtomHashGenerator(seeds, simple, new Xorshift(), MakeStereoEncoderFactory(),
                                                      equivSetFinder, suppression));
            }
            else
            {
                // no equivalence set finder - just use the simple hash
                return(simple);
            }
        }
Example #6
0
        public void TestGenerate_SizeSeeding()
        {
            var m_m1 = new Mock <IAtomContainer>(); var m1 = m_m1.Object;
            var m_m2 = new Mock <IAtomContainer>(); var m2 = m_m2.Object;

            var           m_encoder = new Mock <IAtomEncoder>(); var encoder = m_encoder.Object;
            SeedGenerator generator = new SeedGenerator(encoder);

            var m_c1 = new Mock <IAtom>(); var c1 = m_c1.Object;
            var m_c2 = new Mock <IAtom>(); var c2 = m_c2.Object;
            var m_c3 = new Mock <IAtom>(); var c3 = m_c3.Object;
            var m_c4 = new Mock <IAtom>(); var c4 = m_c4.Object;
            var m_c5 = new Mock <IAtom>(); var c5 = m_c5.Object;
            var m_c6 = new Mock <IAtom>(); var c6 = m_c6.Object;

            m_m1.SetupGet(n => n.Atoms.Count).Returns(5);
            m_m1.SetupGet(n => n.Atoms[0]).Returns(c1);
            m_m1.SetupGet(n => n.Atoms[1]).Returns(c2);
            m_m1.SetupGet(n => n.Atoms[2]).Returns(c3);
            m_m1.SetupGet(n => n.Atoms[3]).Returns(c4);
            m_m1.SetupGet(n => n.Atoms[4]).Returns(c5);

            m_m2.SetupGet(n => n.Atoms.Count).Returns(6);
            m_m2.SetupGet(n => n.Atoms[0]).Returns(c1);
            m_m2.SetupGet(n => n.Atoms[1]).Returns(c2);
            m_m2.SetupGet(n => n.Atoms[2]).Returns(c3);
            m_m2.SetupGet(n => n.Atoms[3]).Returns(c4);
            m_m2.SetupGet(n => n.Atoms[4]).Returns(c5);
            m_m2.SetupGet(n => n.Atoms[5]).Returns(c6);

            m_encoder.Setup(n => n.Encode(c1, m1)).Returns(42);
            m_encoder.Setup(n => n.Encode(c2, m1)).Returns(42);
            m_encoder.Setup(n => n.Encode(c3, m1)).Returns(42);
            m_encoder.Setup(n => n.Encode(c4, m1)).Returns(42);
            m_encoder.Setup(n => n.Encode(c5, m1)).Returns(42);

            m_encoder.Setup(n => n.Encode(c1, m2)).Returns(42);
            m_encoder.Setup(n => n.Encode(c2, m2)).Returns(42);
            m_encoder.Setup(n => n.Encode(c3, m2)).Returns(42);
            m_encoder.Setup(n => n.Encode(c4, m2)).Returns(42);
            m_encoder.Setup(n => n.Encode(c5, m2)).Returns(42);
            m_encoder.Setup(n => n.Encode(c6, m2)).Returns(42);

            long[] v1 = generator.Generate(m1);
            long[] v2 = generator.Generate(m2);

            m_m1.Verify(n => n.Atoms.Count, Times.Exactly(1));
            m_m2.Verify(n => n.Atoms.Count, Times.Exactly(1));

            m_m1.Verify(n => n.Atoms[It.IsAny <int>()], Times.Exactly(5));
            m_m2.Verify(n => n.Atoms[It.IsAny <int>()], Times.Exactly(6));

            m_encoder.Verify(n => n.Encode(c1, m1), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c2, m1), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c3, m1), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c4, m1), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c5, m1), Times.Exactly(1));

            m_encoder.Verify(n => n.Encode(c1, m2), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c2, m2), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c3, m2), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c4, m2), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c5, m2), Times.Exactly(1));
            m_encoder.Verify(n => n.Encode(c6, m2), Times.Exactly(1));

            // check the value were different (due to molecule size)
            Assert.AreEqual(5, v1.Length);
            Assert.AreEqual(6, v2.Length);
            for (int i = 0; i < v1.Length; i++)
            {
                Assert.AreNotEqual(v1[i], v2[i]);
            }

            //VerifyNoMoreInteractions(m1, m2, c1, c2, c3, c4, c5, c6, encoder);
        }