001    /*
002     * Copyright (c) 1998-2014 ChemAxon Ltd. All Rights Reserved.
003     *
004     * This software is the confidential and proprietary information of
005     * ChemAxon. You shall not disclose such Confidential Information
006     * and shall use it only in accordance with the terms of the agreements
007     * you entered into with ChemAxon.
008     *
009     */
010    
011    package com.chemaxon.clustering.common;
012    
013    import chemaxon.struc.Molecule;
014    import com.chemaxon.common.annotations.PublicAPI;
015    import com.chemaxon.descriptors.common.Descriptor;
016    import com.chemaxon.descriptors.common.DescriptorComparator;
017    import com.chemaxon.descriptors.common.DescriptorGenerator;
018    import com.chemaxon.descriptors.metrics.MetricMetadata;
019    import com.google.common.annotations.Beta;
020    import java.util.ArrayList;
021    import java.util.List;
022    
023    /**
024     * Dissimilarity input implementation over Molecule objects and descriptors.
025     *
026     * @param  <D>  Used descriptors bare type
027     *
028     * <p>Please note that this class is marked with @Beta annotation, so it can be subject of incompatible changes or
029     * removal in later releases.</p>
030     *
031     * @author Gabor Imre
032     */
033    @Beta
034    @PublicAPI
035    public class MolInput<D extends Descriptor> implements DissimilarityInput {
036    
037        /**
038         * Underlying descriptor generator.
039         */
040        private final DescriptorGenerator<D> generator;
041    
042        /**
043         * Underlying descriptor comparator.
044         */
045        private final DescriptorComparator<D> comparator;
046    
047        /**
048         * Represented structures.
049         */
050        private final Molecule [] mols;
051    
052        /**
053         * Associated descriptors.
054         */
055        private final List<D> desc;
056    
057        /**
058         * Construct over Molecules.
059         *
060         * @param mols  Molecules to represent
061         * @param gen   Descriptor generator
062         * @param comp  Associated comparator
063         */
064        public MolInput(List<? extends Molecule> mols, DescriptorGenerator<D> gen, DescriptorComparator<D> comp) {
065            this.generator = gen;
066            this.comparator = comp;
067            this.mols = mols.toArray(new Molecule[0]);
068            this.desc = new ArrayList<D>(this.mols.length);
069            for (int i = 0; i < this.mols.length; i++) {
070                this.desc.add(null);
071            }
072        }
073    
074        @Override
075        public int size() {
076            return this.mols.length;
077        }
078    
079        /**
080         * Utility method to ensure that a descriptor is calculated.
081         *
082         * @param index     Structure index
083         * @return          Descriptor associated to index
084         */
085        private D ensureDescriptor(int index) {
086            if (this.desc.get(index) == null) {
087                final D d = this.generator.getBareDescriptor(this.generator.generateDescriptor(this.mols[index]));
088                this.desc.set(index, d);
089            }
090            return this.desc.get(index);
091        }
092    
093        @Override
094        public double dissimilarity(int targetIndex, int queryIndex) {
095            final D q = ensureDescriptor(queryIndex);
096            final D t = ensureDescriptor(targetIndex);
097            return this.comparator.calculateDissimilarity(t, q);
098        }
099    
100        @Override
101        public MetricMetadata getMetricMetadata() {
102            return this.comparator.getMetricMetadata();
103        }
104    
105        /**
106         * Retrieve a structure.
107         *
108         * @param index Structure index
109         * @return      Represented structure
110         */
111        public Molecule getMolecule(int index) {
112            return this.mols[index];
113        }
114    }