/* * Genoogle: Similar DNA Sequences Searching Engine and Tools. (http://genoogle.pih.bio.br) * Copyright (C) 2008,2009,2010,2011,2012 Felipe Fernandes Albrecht (felipe.albrecht@gmail.com) * * For further information check the LICENSE file. */ package bio.pih.genoogle.search; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.ListIterator; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.log4j.Logger; import bio.pih.genoogle.alignment.SubstitutionMatrix; import bio.pih.genoogle.io.RemoteSimilaritySequenceDataBank; import bio.pih.genoogle.search.results.HSP; import bio.pih.genoogle.search.results.Hit; import bio.pih.genoogle.search.results.SearchResults; import com.google.common.collect.Lists; /** * A searcher that does search operation at each data bank of its collection. * * @author albrecht * */ public class RemoteSimilaritySearcher extends AbstractSearcher { private static Logger logger = Logger.getLogger(RemoteSimilaritySearcher.class.getName()); private final RemoteSimilaritySequenceDataBank databank; public RemoteSimilaritySearcher(long code, SearchParams sp, RemoteSimilaritySequenceDataBank databank) { super(code, sp, databank); this.databank = databank; } @Override public SearchResults call() { long begin = System.currentTimeMillis(); ExecutorService queryExecutor = Executors.newFixedThreadPool(sp.getMaxThreadsIndexSearch()); List<Throwable> fails = Lists.newLinkedList(); fails = Collections.synchronizedList(fails); final IndexSixFramesSearcher indexSearcher = new IndexSixFramesSearcher(id, sp, databank, queryExecutor, fails); IndexSearchResults indexSearchResults = null; try { indexSearchResults = indexSearcher.call(); } catch (InterruptedException e) { sr.addFail(e); return sr; } queryExecutor.shutdown(); if (fails.size() > 0) { sr.addAllFails(fails); return sr; } logger.info("Index Searcher " + this.toString() + " " + (System.currentTimeMillis() - begin)); long alignmentBegin = System.currentTimeMillis(); ExecutorService alignerExecutor = Executors.newFixedThreadPool(sp.getMaxThreadsExtendAlign()); int maxHits = sp.getMaxHitsResults() > 0 ? sp.getMaxHitsResults() : indexSearchResults.size(); maxHits = Math.min(maxHits, indexSearchResults.size()); CountDownLatch alignnmentsCountDown = new CountDownLatch(maxHits); try { for (int i = 0; i < maxHits; i++) { RetrievedSequenceAreas retrievedArea = indexSearchResults.get(i); SequenceAligner sequenceAligner = new SequenceAligner(alignnmentsCountDown, indexSearchResults.getIndexSearchers(), retrievedArea, sr, databank, databank.getEncoder(), databank.getAaEncoder(), databank.getReducedEncoder(), // TODO: be possible to set the substitution matrix SubstitutionMatrix.BLOSUM62); alignerExecutor.submit(sequenceAligner); } } catch (IOException e) { sr.addFail(e); return sr; } try { alignnmentsCountDown.await(); } catch (InterruptedException e) { sr.addFail(e); return sr; } alignerExecutor.shutdown(); ListIterator<Hit> hitsIterator = sr.getHits().listIterator(); while (hitsIterator.hasNext()) { Hit hit = hitsIterator.next(); filterHSPs(hit.getHSPs()); if (hit.getHSPs().isEmpty()) { hitsIterator.remove(); } else { Collections.sort(hit.getHSPs(), HSP.COMPARATOR); } } Collections.sort(sr.getHits(), Hit.COMPARATOR); logger.info("Alignments total Time of " + this.toString() + " " + (System.currentTimeMillis() - alignmentBegin)); logger.info("Total Time of " + this.toString() + " " + (System.currentTimeMillis() - begin)); return sr; } private void filterHSPs(List<HSP> HSPs) { ListIterator<HSP> iterator = HSPs.listIterator(); while (iterator.hasNext()) { HSP hsp = iterator.next(); if (hsp.getEValue() >= 0.1) { iterator.remove(); } } } @Override public String toString() { StringBuilder sb = new StringBuilder(Long.toString(id)); sb.append(" CollectionSearcher "); return sb.toString(); } }