/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio.search; import java.io.Serializable; import org.biojava.utils.TriState; import org.biojava.utils.walker.WalkerFactory; /** * A SearchContentHandler class that implements filtering * in chains of SearchContentHandler instances. *

* The SearchContentHandler organise Blast-like searches * as a hierarchy of search/hit/subhit. Each search * is conducted with a single query sequence. Hits * of the query sequence are reported against different * target sequences. The hit is further subdivided into * one of more subhits which represent the positions * within the target sequence that alignments of the query * sequence were achieved against the query sequence * (e.g. HSPs). *

* This implementation depends on the a well ordered use * of the SearchContentHandler interface. In particular, * it requires that search/hit/subhit properties are * reported immediately following the associated * startSearch/startHit/startSubHit call. For example, * search properties should not be reported following * the corresponding startHit() call. *

* Semantics of this interface
* BlastLikeSearchFilters test different levels of the * SearchContentHandler property hierarchy and each * filter should be seen as being applied when a full * set of events from that level is received. So the * ByHitProperty filter is applied when endHit() is * called and determines whether all events received * between startHit() and endHit() are to be passed on * or discarded. *

* Some keys used by SearchContentHandlers
* SearchProperties
* * * * * * * * * * * * * * * * * *
KEY_QUERY_IDString. Value from setQueryID
queryDescriptionString. FASTA description line
programString. variant of BLAST used
versionsoftware version
*

* HitProperties
* * * * * * * * * * * * * * * * * *
subjectIdString. Identity of subject (target) sequence.
subjectSequenceLengthString representation of integer value
subjectDescriptionString.
*

* SubHitProperties
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
bitScoreString representation of real value
queryStrandplus/minus
percentageIdentityString representation of real value
querySequenceEndString representation of integer value
expectValueString representation of real value
subjectStrandplus/minus
subjectSequenceEndString representation of integer value
numberOfPositivesString representation of integer value
scoreString representation of integer value
subjectSequenceString representation of sequence
alignmentSizeString representation of integer value
querySequenceStartString representation of integer value
subjectSequenceStartString representation of integer value
numberOfIdentitiesString representation of integer value
querySequenceString representation of sequence
* * * @author David Huen */ public interface BlastLikeSearchFilter extends Serializable { public interface Node { public Object getSearchProperty(Object key); public Object getHitProperty(Object key); public Object getSubHitProperty(Object key); } public static final String KEY_QUERY_ID = "___QUERY_ID___"; /** * returns a TriState indicating the current outcome * of evaluating this filter. This is usually the * outcome saved when evaluate(FilteringContentHandler fch) was called. */ public TriState accept(); /** * computes the outcome of this filter on the * specified node and stores it. This method * is only exposed to permit it to be included * in an interface. Users should not use it. */ public void evaluate(Node fch); /** * resets the internal state of this filter including * any cached evaluations. This method * is only exposed to permit it to be included * in an interface. Users should not use it. */ public void reset(); public abstract static class AbstractBlastLikeSearchFilter implements BlastLikeSearchFilter { protected TriState cachedOutcome = TriState.INDETERMINATE; public TriState accept() { return cachedOutcome; } abstract public void evaluate(Node fch); public void reset() { cachedOutcome = TriState.INDETERMINATE; } private AbstractBlastLikeSearchFilter() {} } public static final class And { static { WalkerFactory.getInstance().addTypeWithParent(And.class); } private AbstractBlastLikeSearchFilter filter0; private AbstractBlastLikeSearchFilter filter1; public And( AbstractBlastLikeSearchFilter filter0, AbstractBlastLikeSearchFilter filter1) { this.filter0 = filter0; this.filter1 = filter1; } public TriState accept() { TriState outcome0 = filter0.accept(); TriState outcome1 = filter1.accept(); if ((outcome0 == TriState.FALSE) || (outcome1 == TriState.FALSE)) return TriState.FALSE; // neither can be false now if ((outcome0 == TriState.INDETERMINATE) || (outcome1 == TriState.INDETERMINATE)) return TriState.INDETERMINATE; // neither is false nor indeterminate so it must be true! return TriState.TRUE; } } public static final class Or { static { WalkerFactory.getInstance().addTypeWithParent(Or.class); } private AbstractBlastLikeSearchFilter filter0; private AbstractBlastLikeSearchFilter filter1; public Or( AbstractBlastLikeSearchFilter filter0, AbstractBlastLikeSearchFilter filter1) { this.filter0 = filter0; this.filter1 = filter1; } public TriState accept() { TriState outcome0 = filter0.accept(); TriState outcome1 = filter1.accept(); if ((outcome0 == TriState.TRUE) || (outcome1 == TriState.TRUE)) return TriState.TRUE; // neither can be false now if ((outcome0 == TriState.INDETERMINATE) || (outcome1 == TriState.INDETERMINATE)) return TriState.INDETERMINATE; // neither is true nor indeterminate so it must be false! return TriState.FALSE; } } public static final class Not extends AbstractBlastLikeSearchFilter { static { WalkerFactory.getInstance().addTypeWithParent(Not.class); } private AbstractBlastLikeSearchFilter filter; public Not(AbstractBlastLikeSearchFilter filter) { this.filter = filter; } public TriState accept() { TriState outcome = filter.accept(); if (outcome == TriState.INDETERMINATE) return TriState.INDETERMINATE; if (outcome == TriState.TRUE) return TriState.FALSE; else return TriState.TRUE; } public void evaluate(Node fch) {} } /** * Applies test to the value specified by the key in search properties. */ public static final class BySearchProperty extends AbstractBlastLikeSearchFilter { private Object key; private FilterTest test; public BySearchProperty(String key, FilterTest test) { this.key = key; this.test = test; } public void evaluate(Node fch) { Object propertyValue = fch.getSearchProperty(key); cachedOutcome = ((propertyValue != null) && test.accept(propertyValue)) ? TriState.TRUE : TriState.FALSE; } } /** * Applies test to the value specified by the key in hit properties. */ public static final class ByHitProperty extends AbstractBlastLikeSearchFilter { private Object key; private FilterTest test; public ByHitProperty(String key, FilterTest test) { this.key = key; this.test = test; } public void evaluate(Node fch) { Object propertyValue = fch.getHitProperty(key); cachedOutcome = ((propertyValue != null) && test.accept(propertyValue)) ? TriState.TRUE : TriState.FALSE; } } /** * Applies test to the value specified by the key in subhit properties. */ public static final class BySubHitProperty extends AbstractBlastLikeSearchFilter { private Object key; private FilterTest test; public BySubHitProperty(String key, FilterTest test) { this.key = key; this.test = test; } public void evaluate(Node fch) { Object propertyValue = fch.getSubHitProperty(key); //cachedOutcome = ((propertyValue == null) // ? TriState.INDETERMINATE // : (test.accept(propertyValue)) ? TriState.TRUE : TriState.FALSE); cachedOutcome = ((propertyValue != null) && test.accept(propertyValue)) ? TriState.TRUE : TriState.FALSE; } } }