All Downloads are FREE. Search and download functionalities are using the official Maven repository.

maltcms.commands.distances.PairwiseFeatureSimilarity Maven / Gradle / Ivy

Go to download

Similarities for Feature Vectors and Time Series thereof, such as Cosine and Dynamic Time Warping.

The newest version!
/*
 * Maltcms, modular application toolkit for chromatography-mass spectrometry.
 * Copyright (C) 2008-2014, The authors of Maltcms. All rights reserved.
 *
 * Project website: http://maltcms.sf.net
 *
 * Maltcms may be used under the terms of either the
 *
 * GNU Lesser General Public License (LGPL)
 * http://www.gnu.org/licenses/lgpl.html
 *
 * or the
 *
 * Eclipse Public License (EPL)
 * http://www.eclipse.org/org/documents/epl-v10.php
 *
 * As a user/recipient of Maltcms, you may choose which license to receive the code
 * under. Certain files or entire directories may not be covered by this
 * dual license, but are subject to licenses compatible to both LGPL and EPL.
 * License exceptions are explicitly declared in all relevant files or in a
 * LICENSE file in the relevant directories.
 *
 * Maltcms is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. Please consult the relevant license documentation
 * for details.
 */
package maltcms.commands.distances;

import cross.Factory;
import cross.IConfigurable;
import cross.annotations.Configurable;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import maltcms.datastructures.array.IArrayD2Double;
import maltcms.math.functions.DtwTimePenalizedPairwiseSimilarity;
import org.apache.commons.configuration.Configuration;
import org.slf4j.LoggerFactory;
import ucar.ma2.Array;
import ucar.ma2.ArrayDouble;

/**
 * Class used to calculate a pairwise score or cost between mass-spectra.
 * Objects of this class are used in
 * {@link maltcms.commands.distances.dtw.ADynamicTimeWarp} to calculate the
 * distance/similiarity between scans, as configured.
 *
 * @author Nils Hoffmann
 * 
 */

@Data
public class PairwiseFeatureSimilarity implements IConfigurable {

    private static final org.slf4j.Logger log = LoggerFactory.getLogger(PairwiseFeatureSimilarity.class);

    /**
     *
     */
    private static final long serialVersionUID = -2087449317783907180L;
    @Configurable(name = "alignment.algorithm.distance")
    private IDtwSimilarityFunction similarityFunction = new DtwTimePenalizedPairwiseSimilarity();
    @Configurable(name = "cross.Factory.maxthreads")
    private int nthreads = 1;
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private IArrayD2Double pad = null;

    private void calcPWD(final Executor e,
            final Collection> solvers,
            final IArrayD2Double pairwiseDistance) throws InterruptedException,
            ExecutionException {
        final CompletionService ecs = new ExecutorCompletionService<>(
                e);
        for (final Callable s : solvers) {
            ecs.submit(s);
        }
        final int n = solvers.size();
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
            final Integer r = ecs.take().get();
            if (r > 0) {
                cnt += r;
                // log.info("Calculated {}/{} similarities/distances",cnt,
                // pairwiseDistance.getNumberOfStoredElements());
            }
        }
        log.info("Calculated {}/{} similarities/distances", cnt,
                pairwiseDistance.getNumberOfStoredElements());
    }

    /**
     * This method can be called for precalculation of all
     * distances/similarites. Values are set within the paramter ArrayDouble.D2
     * d and can be retrieved from it.
     *
     * @param d a {@link maltcms.datastructures.array.IArrayD2Double} object.
     * @param ref a {@link java.util.List} object.
     * @param query a {@link java.util.List} object.
     * @param satRef1 a {@link ucar.ma2.ArrayDouble.D1} object.
     * @param satQuery1 a {@link ucar.ma2.ArrayDouble.D1} object.
     */
    public void calculatePairwiseDistances(final IArrayD2Double d,
            final ArrayDouble.D1 satRef1, final ArrayDouble.D1 satQuery1,
            final List ref, final List query) {
        if (this.nthreads == 1) {
            log.info("Skipping precalculation, only one thread available!");
            return;
        }

        final ArrayDouble.D1 satRef = (satRef1 == null) ? new ArrayDouble.D1(
                ref.size()) : satRef1;
        final ArrayDouble.D1 satQuery = (satQuery1 == null) ? new ArrayDouble.D1(
                query.size())
                : satQuery1;

        final int rows = ref.size();
        final int cols = query.size();
        final float nelements = (rows * cols);
        // float onebynelemens = 1.0f / nelements;
        log.info("Calculating {} elements", nelements);
        int i = 0;
        int j = 0;
        this.pad = d;
        final ExecutorService es = Executors.newFixedThreadPool(this.nthreads);
        // int threadpoolsize = Math.max(1, Math.min(50, Math.max(sx, sy)/10));
        // ExecutorService es = Executors.newFixedThreadPool(nthreads);
        log.info("Precalculating the distance matrix with {} thread(s)!",
                this.nthreads);
        final int tilesRows = 2;
        final int tilesCols = 2;
        final int tileSizeRows = (int) Math.ceil((float) rows
                / (float) tilesRows);
        final int tileSizeCols = (int) Math.ceil((float) cols
                / (float) tilesCols);
        final ArrayList> solvers = new ArrayList<>();
        for (i = 0; i < tilesRows; i++) {
            for (j = 0; j < tilesCols; j++) {
                final Rectangle r = new Rectangle(i * tileSizeCols, j
                        * tileSizeRows, tileSizeCols, tileSizeRows);
                log.debug("Creating rectangle: {}", r);
                final PartitionCalculator pc = new PartitionCalculator(r,
                        this.pad, satRef, satQuery, ref, query);
                pc.configure(Factory.getInstance().getConfiguration());
                solvers.add(pc);
            }
        }
        try {
            calcPWD(es, solvers, this.pad);
        } catch (final InterruptedException | ExecutionException e) {
            log.error(e.getLocalizedMessage());
        }
    }

    /** {@inheritDoc} */
    @Override
    public void configure(final Configuration cfg) {
//        final String aldist = "maltcms.commands.distances.ArrayLp";
//        this.costFunction = Factory.getInstance().getObjectFactory().instantiate(
//                cfg.getString("alignment.algorithm.distance", aldist),
//                IDtwSimilarityFunction.class);
//        log.info("Using {}", this.costFunction.getClass().getName());
        // this.nthreads = cfg.getInt("cross.Factory.maxthreads", 1);
    }

    /**
     * Returns the IDtwSimilarityFunction Object used to calculate pairwise
     * distances/similarities.
     *
     * @param i a int.
     * @param j a int.
     * @param time_i a double.
     * @param time_j a double.
     * @param a a {@link ucar.ma2.Array} object.
     * @param b a {@link ucar.ma2.Array} object.
     * @return a double.
     */
//    public IDtwSimilarityFunction getDistance() {
//        return this.similarityFunction;
//    }
    public double getDistance(final int i, final int j, final double time_i,
            final double time_j, final Array a, final Array b) {
        double d = 0.0d;
        if (this.pad == null) {
            d = this.similarityFunction.apply(i, j, time_i, time_j, a, b);
        } else {
            return this.pad.get(i, j);
        }
        return d;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy