001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021 022package org.biojava.bio.seq.homol; 023 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.Iterator; 027import java.util.List; 028import java.util.NoSuchElementException; 029import java.util.Set; 030 031import org.biojava.bio.alignment.Alignment; 032import org.biojava.bio.seq.StrandedFeature; 033import org.biojava.bio.symbol.Alphabet; 034import org.biojava.bio.symbol.Edit; 035import org.biojava.bio.symbol.IllegalAlphabetException; 036import org.biojava.bio.symbol.Location; 037import org.biojava.bio.symbol.Symbol; 038import org.biojava.bio.symbol.SymbolList; 039import org.biojava.utils.ChangeType; 040import org.biojava.utils.ChangeVetoException; 041import org.biojava.utils.Unchangeable; 042 043/** 044 * <p><code>SimilarityPairFeature</code> describes a pairwise 045 * similarity between two nucleotide sequences (as it extends 046 * <code>StrandedFeature</code>). It is analagous to, and based on, 047 * the BioPerl Bio::SeqFeature::SimilarityPair.</p> 048 * 049 * <p>It is different from <code>HomologyFeature</code> in that it 050 * expresses a relationship between only two sequence regions (rather 051 * than >= 2), with one clearly defined as the query sequence and the 052 * other as the subject (database hit). These are identified by 053 * constant labels in the 054 * <code>Alignment</code>. <code>HomologyFeature</code> identifies the 055 * related sequence regions by means of an <code>Homology</code> 056 * instance which contains an <code>Alignment</code> which uses the 057 * <code>HomologyFeature</code>s themselves as labels.</p> 058 * 059 * <p>In cases where there is no alignment available, for example when 060 * MSPCrunch output or GFF have been used, the 061 * <code>EmptyPairwiseAlignment</code> in the EMPTY_PAIRWISE field may 062 * be used. This may also be useful if an implementation elides the 063 * alignment data for some reason.</p> 064 * 065 * @author Keith James 066 * @since 1.2 067 */ 068public interface SimilarityPairFeature extends StrandedFeature 069{ 070 /** 071 * The sibling of this feature has altered. 072 */ 073 public static final ChangeType SIBLING = 074 new ChangeType("Sibling has altered", SimilarityPairFeature.class, "SIBLING"); 075 076 /** 077 * Constant <code>QUERY_LABEL</code> is the alignment label used 078 * for all query sequences. 079 */ 080 public static final String QUERY_LABEL = "query"; 081 082 /** 083 * Constant <code>SUBJECT_LABEL</code> is the alignment label used 084 * for all subject sequences. 085 */ 086 public static final String SUBJECT_LABEL = "subject"; 087 088 /** 089 * Constant <code>EMPTY_PAIRWISE</code> is an empty alignment for 090 * situations where there is no available alignment data or the 091 * implementation does not want to create one. 092 */ 093 public static final Alignment EMPTY_PAIRWISE = new EmptyPairwiseAlignment(); 094 095 /** 096 * <code>getSibling</code> returns the sibling 097 * <code>Feature</code>, query for subject and vice versa. 098 * 099 * @return a <code>Feature</code>. 100 */ 101 public SimilarityPairFeature getSibling(); 102 103 /** 104 * <code>setSibling</code> sets the sibling feature of the 105 * pair. This is used to set the reciprocal 106 * <code>SimilarityPairFeature</code> as both cannot be set using 107 * the <code>Template</code>. 108 */ 109 public void setSibling(SimilarityPairFeature sibling) 110 throws ChangeVetoException; 111 112 /** 113 * <code>getAlignment</code> returns the <code>Alignment</code> of 114 * two similar features. 115 * 116 * @return an <code>Alignment</code> value. 117 */ 118 public Alignment getAlignment(); 119 120 /** 121 * <code>getScore</code> returns the alignment score. 122 * 123 * @return a <code>double</code>. 124 */ 125 public double getScore(); 126 127 /** 128 * <code>Template</code> for construction of 129 * <code>SimilarityPairFeature</code>s. 130 */ 131 public static class Template extends StrandedFeature.Template 132 { 133 /** 134 * <code>sibling</code> <code>SimilarityPairFeature</code> 135 * field. May be null if the reciprocal 136 * <code>SimilarityPairFeature</code> has not yet been 137 * created. 138 */ 139 public SimilarityPairFeature sibling; 140 141 /** 142 * <code>alignment</code> <code>Alignment</code> field. 143 */ 144 public Alignment alignment; 145 146 /** 147 * <code>score</code> of the search which produced the 148 * alignment. 149 */ 150 public double score; 151 } 152 153 /** 154 * <code>EmptyPairwiseAlignment</code> empty pairwise alignment 155 * which has labels to empty symbol lists. 156 */ 157 static final class EmptyPairwiseAlignment extends Unchangeable 158 implements Alignment 159 { 160 private List<String> labels = new ArrayList<String>(2); 161 162 EmptyPairwiseAlignment() 163 { 164 labels = new ArrayList<String>(2); 165 labels.add(QUERY_LABEL); 166 labels.add(SUBJECT_LABEL); 167 } 168 169 public List<String> getLabels() 170 { 171 return labels; 172 } 173 174 public Symbol symbolAt(String label, int index) 175 throws NoSuchElementException 176 { 177 throw new NoSuchElementException("Attempted to retrieve symbol from empty list at " 178 + label 179 + ":" 180 + index); 181 } 182 183 public SymbolList symbolListForLabel(String label) 184 throws NoSuchElementException 185 { 186 return SymbolList.EMPTY_LIST; 187 } 188 189 public Alignment subAlignment(Set<String> labels, Location loc) 190 throws NoSuchElementException 191 { 192 throw new NoSuchElementException("Attempted to retrieve sub-alignment from empty list at " 193 + labels 194 + ":" 195 + loc); 196 } 197 198 public int length() 199 { 200 return 0; 201 } 202 203 public Iterator iterator() 204 { 205 return Collections.EMPTY_LIST.iterator(); 206 } 207 208 public SymbolList subList(int index1, int index2) 209 throws IndexOutOfBoundsException 210 { 211 Collections.EMPTY_LIST.subList(index1 - 1, index2); 212 return SymbolList.EMPTY_LIST; 213 } 214 215 public Symbol symbolAt(int index) throws IndexOutOfBoundsException 216 { 217 throw new IndexOutOfBoundsException("Attempted to retrieve symbol from empty list at " 218 + index); 219 } 220 221 public Alphabet getAlphabet() 222 { 223 return Alphabet.EMPTY_ALPHABET; 224 } 225 226 public List toList() 227 { 228 return Collections.EMPTY_LIST; 229 } 230 231 public String seqString() 232 { 233 return ""; 234 } 235 236 public String subStr(int index1, int index2) 237 throws IndexOutOfBoundsException 238 { 239 throw new IndexOutOfBoundsException("You can not retrieve part of an empty symbol list"); 240 } 241 242 public void edit(Edit edit) 243 throws IndexOutOfBoundsException,IllegalAlphabetException, 244 ChangeVetoException 245 { 246 throw new ChangeVetoException("You can't edit the empty symbol list"); 247 } 248 249 public Iterator<SymbolList> symbolListIterator() 250 { 251 return new Alignment.SymbolListIterator(this); 252 } 253 } 254}