/// <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()"); }
/// <summary> /// Discriminate atoms experiencing uniform environments using the provided /// method. Depending on the level of identity required one can choose how /// the atoms a perturbed in an attempt to break symmetry. As with all /// hashing there is always a probability of collision but some of these /// collisions may be due to an insufficiency in the algorithm opposed to a /// random chance of collision. Currently there are three strategies but one /// should choose either to use the fast, but good, heuristic <see cref="MinimumEquivalentCyclicSet"/> /// or the exact <see cref="AllEquivalentCyclicSet"/>. /// In practice <see cref="MinimumEquivalentCyclicSet"/> is good enough for most /// applications but it is important to understand the potential trade off. /// The <see cref="MinimumEquivalentCyclicSetUnion"/> is provided for demonstration /// only, and as such, is deprecated. /// /// <list type="bullet"> /// <item>MinimumEquivalentCyclicSet - fastest, attempt to break symmetry /// by changing a single smallest set of the equivalent atoms which occur in /// a ring</item> /// <item><strike>MinimumEquivalentCyclicSetUnion</strike> /// (deprecated) - distinguishes more molecules by changing all smallest sets /// of the equivalent atoms which occur in a ring. This method is provided /// from example only</item> /// <item>AllEquivalentCyclicSet - slowest, /// systematically perturb all equivalent atoms that occur in a ring</item> /// </list> /// /// At the time of writing (Feb, 2013) the number of known false possibles /// found in PubChem-Compound (aprx. 46,000,000 structures) are as follows: /// <list type="bullet"> /// <item>MinimumEquivalentCyclicSet - 128 molecules, 64 false positives (128/2)</item> /// <item>MinimumEquivalentCyclicSetUnion - 8 molecules, 4 false positives (8/2)</item> /// <item>AllEquivalentCyclicSet - 0 molecules</item> /// </list> /// </summary> /// <param name="equivSetFinder">equivalent set finder, used to determine which atoms will be perturbed to try and break symmetry.</param> /// <returns>fluent API reference (self)</returns> /// <seealso cref="AllEquivalentCyclicSet"/> /// <seealso cref="MinimumEquivalentCyclicSet"/> /// <seealso cref="MinimumEquivalentCyclicSetUnion"/> internal HashGeneratorMaker PerturbWith(EquivalentSetFinder equivSetFinder) { this.equivSetFinder = equivSetFinder; return(this); }