/// <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>()); }
/// <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)); }
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); }
/// <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); } }
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); }