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

org.nmdp.ngs.align.ParallelBiojavaPairwiseAlignment Maven / Gradle / Ivy

There is a newer version: 1.8.3
Show newest version
/*

    ngs-align  Sequence alignment.
    Copyright (c) 2014-2015 National Marrow Donor Program (NMDP)

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 3 of the License, or (at
    your option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
    License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this library;  if not, write to the Free Software Foundation,
    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.

    > http://www.gnu.org/licenses/lgpl.html

*/
package org.nmdp.ngs.align;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collections;
import java.util.List;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import com.google.common.collect.Lists;

import org.biojava.bio.alignment.AlignmentPair;
import org.biojava.bio.alignment.NeedlemanWunsch;
import org.biojava.bio.alignment.SmithWaterman;
import org.biojava.bio.alignment.SubstitutionMatrix;

import org.biojava.bio.seq.Sequence;

/**
 * Parallel implementation of PairwiseAlignment based on Biojava.
 */
public final class ParallelBiojavaPairwiseAlignment extends AbstractPairwiseAlignment {
    /** Executor service. */
    private final ExecutorService executorService;


    private ParallelBiojavaPairwiseAlignment(final ExecutorService executorService,
                                             final SubstitutionMatrix substitutionMatrix) {
        super(substitutionMatrix);
        this.executorService = executorService;
    }


    @Override
    public Iterable local(final List queries,
                                         final List subjects,
                                         final GapPenalties gapPenalties) {
        checkNotNull(queries);
        checkNotNull(subjects);
        checkNotNull(gapPenalties);

        if (queries.isEmpty() || subjects.isEmpty()) {
            return Collections.emptyList();
        }

        List tasks = Lists.newArrayListWithExpectedSize(queries.size() * subjects.size());
        for (Sequence query : queries) {
            for (Sequence subject : subjects) {
                tasks.add(new SmithWatermanTask(query, subject, gapPenalties, getSubstitutionMatrix()));
            }
        }

        List alignmentPairs = Lists.newArrayListWithExpectedSize(queries.size() * subjects.size());
        try {
            List> futures = executorService.invokeAll(tasks);

            for (Future future : futures) {
                alignmentPairs.add(future.get());
            }
        }
        catch (ExecutionException | InterruptedException e) {
            // todo
        }
        return alignmentPairs;
    }

    @Override
    public Iterable global(final List queries,
                                          final List subjects,
                                          final GapPenalties gapPenalties) {
        checkNotNull(queries);
        checkNotNull(subjects);
        checkNotNull(gapPenalties);

        if (queries.isEmpty() || subjects.isEmpty()) {
            return Collections.emptyList();
        }

        List tasks = Lists.newArrayListWithExpectedSize(queries.size() * subjects.size());
        for (Sequence query : queries) {
            for (Sequence subject : subjects) {
                tasks.add(new NeedlemanWunschTask(query, subject, gapPenalties, getSubstitutionMatrix()));
            }
        }

        List alignmentPairs = Lists.newArrayListWithExpectedSize(queries.size() * subjects.size());
        try {
            List> futures = executorService.invokeAll(tasks);

            for (Future future : futures) {
                alignmentPairs.add(future.get());
            }
        }
        catch (ExecutionException | InterruptedException e) {
            // todo
        }
        return alignmentPairs;
    }

    /**
     * Smith-Waterman task.
     */
    private static final class SmithWatermanTask implements Callable {
        private final Sequence query;
        private final Sequence subject;
        private final GapPenalties gapPenalties;
        private final SubstitutionMatrix substitutionMatrix;

        private SmithWatermanTask(final Sequence query,
                                  final Sequence subject,
                                  final GapPenalties gapPenalties,
                                  final SubstitutionMatrix substitutionMatrix) {
            this.query = query;
            this.subject = subject;
            this.gapPenalties = gapPenalties;
            this.substitutionMatrix = substitutionMatrix;
        }

        @Override
        public AlignmentPair call() {
            SmithWaterman smithWaterman = new SmithWaterman(gapPenalties.match(),
                                                            gapPenalties.replace(),
                                                            gapPenalties.insert(),
                                                            gapPenalties.delete(),
                                                            gapPenalties.extend(),
                                                            substitutionMatrix);
            return smithWaterman.pairwiseAlignment(query, subject);
        }
    }

    /**
     * Needleman-Wunsch task.
     */
    private static final class NeedlemanWunschTask implements Callable {
        private final Sequence query;
        private final Sequence subject;
        private final GapPenalties gapPenalties;
        private final SubstitutionMatrix substitutionMatrix;

        private NeedlemanWunschTask(final Sequence query,
                                    final Sequence subject,
                                    final GapPenalties gapPenalties,
                                    final SubstitutionMatrix substitutionMatrix) {
            this.query = query;
            this.subject = subject;
            this.gapPenalties = gapPenalties;
            this.substitutionMatrix = substitutionMatrix;
        }

        @Override
        public AlignmentPair call() throws Exception {
            NeedlemanWunsch needlemanWunsch = new NeedlemanWunsch(gapPenalties.match(),
                                                                  gapPenalties.replace(),
                                                                  gapPenalties.insert(),
                                                                  gapPenalties.delete(),
                                                                  gapPenalties.extend(),
                                                                  substitutionMatrix);
            return needlemanWunsch.pairwiseAlignment(query, subject);
        }
    }

    /**
     * Create and return a new pairwise alignment implementation configured with a cached thread pool and the default
     * substitution matrix (NUC.4.4.txt).
     *
     * @return a new pairwise alignment implementation configured with a cached thread pool and the default
     *    substitution matrix (NUC.4.4.txt)
     */
    public static PairwiseAlignment create() {
        return create(SubstitutionMatrix.getNuc4_4());
    }

    /**
     * Create and return a new pairwise alignment implementation configured with a fixed thread pool and the default
     * substitution matrix (NUC.4.4.txt).
     *
     * @param threads number of threads, must be >= 0
     * @return a new pairwise alignment implementation configured with a fixed thread pool and the default
     *    substitution matrix (NUC.4.4.txt)
     */
    public static PairwiseAlignment create(final int threads) {
        return create(threads, SubstitutionMatrix.getNuc4_4());
    }

    /**
     * Create and return a new pairwise alignment implementation configured with a cached thread pool and the specified
     * substitution matrix.
     *
     * @param substitutionMatrix substitution matrix, must not be null
     * @return a new pairwise alignment implementation configured with a cached thread pool and the specified
     *    substitution matrix
     */
    public static PairwiseAlignment create(final SubstitutionMatrix substitutionMatrix) {
        return new ParallelBiojavaPairwiseAlignment(Executors.newCachedThreadPool(), substitutionMatrix);
    }

    /**
     * Create and return a new pairwise alignment implementation configured with a fixed thread pool and the specified
     * substitution matrix.
     *
     * @param threads number of threads, must be >= 0
     * @param substitutionMatrix substitution matrix, must not be null
     * @return a new pairwise alignment implementation configured with a fixed thread pool and the specified
     *    substitution matrix
     */
    public static PairwiseAlignment create(final int threads, final SubstitutionMatrix substitutionMatrix) {
        return new ParallelBiojavaPairwiseAlignment(Executors.newFixedThreadPool(threads), substitutionMatrix);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy