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.search; 023 024import org.biojava.bio.Annotatable; 025import org.biojava.bio.Annotation; 026import org.biojava.bio.alignment.Alignment; 027import org.biojava.bio.seq.StrandedFeature.Strand; 028import org.biojava.utils.AbstractChangeable; 029import org.biojava.utils.ChangeForwarder; 030import org.biojava.utils.ChangeListener; 031import org.biojava.utils.ChangeSupport; 032import org.biojava.utils.ChangeType; 033import org.biojava.utils.ObjectUtil; 034 035/** 036 * <p><code>SequenceDBSearchSubHit</code> objects represent sub-hits 037 * which make up a hit. In the case of Blast these correspond to 038 * HSPs.</p> 039 * 040 * @author Keith James 041 * @since 1.1 042 * @deprecated SimpleSeqSimilaritySearchSubHit has been made 043 * Annotatable and is now functionally identical. 044 * @see SeqSimilaritySearchSubHit 045 */ 046public class SequenceDBSearchSubHit extends AbstractChangeable 047 implements SeqSimilaritySearchSubHit 048{ 049 protected transient ChangeForwarder annotationForwarder; 050 051 private double score; 052 private double pValue; 053 private double eValue; 054 private int queryStart; 055 private int queryEnd; 056 private Strand queryStrand; 057 private int subjectStart; 058 private int subjectEnd; 059 private Strand subjectStrand; 060 private Alignment alignment; 061 private Annotation annotation; 062 063 // Hashcode is cached after first calculation because the data on 064 // which is is based do not change 065 private int hc; 066 private boolean hcCalc; 067 068 /** 069 * Creates a new <code>SequenceDBSearchSubHit</code> object. 070 * 071 * @param queryStart an <code>int</code> value indicating the 072 * start coordinate of the hit on the query sequence. 073 * @param queryEnd an <code>int</code> value indicating the end 074 * coordinate of the hit on the query sequence. 075 * @param queryStrand a <code>Strand</code> object indicating the 076 * strand of the hit with respect to the query sequence, which may 077 * be null for protein similarities. 078 * @param subjectStart an <code>int</code> value indicating the 079 * start coordinate of the hit on the subject sequence. 080 * @param subjectEnd an <code>int</code> value indicating the end 081 * coordinate of the hit on the query sequence. 082 * @param subjectStrand a <code>Strand</code> object indicating 083 * the strand of the hit with respect to the query sequence, which 084 * may be null for protein similarities. 085 * @param score a <code>double</code> value; the score of the 086 * subhit, which may not be NaN. 087 * @param eValue a <code>double</code> the E-value of the 088 * subhit, which may be NaN. 089 * @param pValue a <code>double</code> value; the P-value of the 090 * hit, which may be NaN. 091 * @param alignment an <code>Alignment</code> object containing 092 * the alignment described by the subhit region, which may not be 093 * null. 094 * @param annotation an <code>Annotation</code> object, which may 095 * not be null. 096 */ 097 public SequenceDBSearchSubHit(double score, 098 double eValue, 099 double pValue, 100 int queryStart, 101 int queryEnd, 102 Strand queryStrand, 103 int subjectStart, 104 int subjectEnd, 105 Strand subjectStrand, 106 Alignment alignment, 107 Annotation annotation) 108 { 109 if (Double.isNaN(score)) 110 { 111 throw new IllegalArgumentException("score was NaN"); 112 } 113 114 // pValue may be NaN 115 // eValue may be NaN 116 if (alignment == null) 117 { 118 throw new IllegalArgumentException("alignment was null"); 119 } 120 121 if (annotation == null) 122 { 123 throw new IllegalArgumentException("annotation was null"); 124 } 125 126 this.score = score; 127 this.eValue = eValue; 128 this.pValue = pValue; 129 this.queryStart = queryStart; 130 this.queryEnd = queryEnd; 131 this.queryStrand = queryStrand; 132 this.subjectStart = subjectStart; 133 this.subjectEnd = subjectEnd; 134 this.subjectStrand = subjectStrand; 135 this.alignment = alignment; 136 this.annotation = annotation; 137 138 // Lock alignment by vetoing all changes 139 this.alignment.addChangeListener(ChangeListener.ALWAYS_VETO); 140 141 // Lock the annotation by vetoing all changes to properties 142 annotation.addChangeListener(ChangeListener.ALWAYS_VETO); 143 144 hcCalc = false; 145 } 146 147 public double getScore() 148 { 149 return score; 150 } 151 152 public double getPValue() 153 { 154 return pValue; 155 } 156 157 public double getEValue() 158 { 159 return eValue; 160 } 161 162 public int getQueryStart() 163 { 164 return queryStart; 165 } 166 167 public int getQueryEnd() 168 { 169 return queryEnd; 170 } 171 172 public Strand getQueryStrand() 173 { 174 return queryStrand; 175 } 176 177 public int getSubjectStart() 178 { 179 return subjectStart; 180 } 181 182 public int getSubjectEnd() 183 { 184 return subjectEnd; 185 } 186 187 public Strand getSubjectStrand() 188 { 189 return subjectStrand; 190 } 191 192 public Alignment getAlignment() 193 { 194 return alignment; 195 } 196 197 public Annotation getAnnotation() 198 { 199 return annotation; 200 } 201 202 public boolean equals(Object other) 203 { 204 if (other == this) return true; 205 if (other == null) return false; 206 207 if (! other.getClass().equals(this.getClass())) return false; 208 209 SequenceDBSearchSubHit that = (SequenceDBSearchSubHit) other; 210 211 if (! ObjectUtil.equals(this.score, that.score)) 212 return false; 213 if (! ObjectUtil.equals(this.pValue, that.pValue)) 214 return false; 215 if (! ObjectUtil.equals(this.eValue, that.eValue)) 216 return false; 217 if (! ObjectUtil.equals(this.queryStart, that.queryStart)) 218 return false; 219 if (! ObjectUtil.equals(this.queryEnd, that.queryEnd)) 220 return false; 221 if (! ObjectUtil.equals(this.queryStrand, that.queryStrand)) 222 return false; 223 if (! ObjectUtil.equals(this.subjectStart, that.subjectStart)) 224 return false; 225 if (! ObjectUtil.equals(this.subjectEnd, that.subjectEnd)) 226 return false; 227 if (! ObjectUtil.equals(this.subjectStrand, that.subjectStrand)) 228 return false; 229 if (! ObjectUtil.equals(this.annotation, that.annotation)) 230 return false; 231 232 return true; 233 } 234 235 public int hashCode() 236 { 237 if (! hcCalc) 238 { 239 hc = ObjectUtil.hashCode(hc, score); 240 hc = ObjectUtil.hashCode(hc, pValue); 241 hc = ObjectUtil.hashCode(hc, eValue); 242 hc = ObjectUtil.hashCode(hc, queryStart); 243 hc = ObjectUtil.hashCode(hc, queryEnd); 244 hc = ObjectUtil.hashCode(hc, queryStrand); 245 hc = ObjectUtil.hashCode(hc, subjectStart); 246 hc = ObjectUtil.hashCode(hc, subjectEnd); 247 hc = ObjectUtil.hashCode(hc, subjectStrand); 248 hc = ObjectUtil.hashCode(hc, annotation); 249 hcCalc = true; 250 } 251 252 return hc; 253 } 254 255 public String toString() 256 { 257 return "SequenceDBSearchSubHit with score " + getScore(); 258 } 259 260 protected ChangeSupport getChangeSupport(ChangeType ct) 261 { 262 ChangeSupport cs = super.getChangeSupport(ct); 263 264 if (annotationForwarder == null && 265 (ct.isMatchingType(Annotatable.ANNOTATION) || Annotatable.ANNOTATION.isMatchingType(ct))) 266 { 267 annotationForwarder = 268 new ChangeForwarder.Retyper(this, cs, Annotation.PROPERTY); 269 getAnnotation().addChangeListener(annotationForwarder, 270 Annotatable.ANNOTATION); 271 } 272 273 return cs; 274 } 275}