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 */ 021package org.biojava.nbio.core.search.io; 022 023import java.util.ArrayList; 024import java.util.List; 025import org.biojava.nbio.core.alignment.SimpleAlignedSequence; 026import org.biojava.nbio.core.alignment.SimpleSequencePair; 027import org.biojava.nbio.core.alignment.template.AlignedSequence.Step; 028import org.biojava.nbio.core.alignment.template.SequencePair; 029import org.biojava.nbio.core.exceptions.CompoundNotFoundException; 030import org.biojava.nbio.core.sequence.DNASequence; 031import org.biojava.nbio.core.sequence.ProteinSequence; 032import org.biojava.nbio.core.sequence.RNASequence; 033import org.biojava.nbio.core.sequence.compound.AminoAcidCompoundSet; 034import org.biojava.nbio.core.sequence.compound.DNACompoundSet; 035import org.biojava.nbio.core.sequence.template.Compound; 036import org.biojava.nbio.core.sequence.template.Sequence; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040/** 041 * This class models a search Hsp. 042 * You will retrieve a list of this using iterator of a Hit 043 * 044 * Designed by Paolo Pavan. 045 * You may want to find my contacts on Github and LinkedIn for code info 046 * or discuss major changes. 047 * https://github.com/paolopavan 048 * 049 * @author Paolo Pavan 050 */ 051 052public abstract class Hsp <S extends Sequence<C>, C extends Compound> { 053 private static final Logger logger = LoggerFactory.getLogger(Hsp.class); 054 private Integer hspNum; 055 private Double hspBitScore; 056 private Integer hspScore; 057 private Double hspEvalue; 058 private Integer hspQueryFrom; 059 private Integer hspQueryTo; 060 private Integer hspHitFrom; 061 private Integer hspHitTo; 062 private Integer hspQueryFrame; 063 private Integer hspHitFrame; 064 private Integer hspIdentity; 065 private Integer hspPositive; 066 private Integer hspGaps; 067 private Integer hspAlignLen; 068 private String hspQseq; 069 private String hspHseq; 070 private String hspIdentityString; 071 private Double percentageIdentity = null; 072 private Integer mismatchCount = null; 073 private SimpleSequencePair<S, C> returnAln; 074 075 @Override 076 public int hashCode() { 077 int hash = 5; 078 hash = 67 * hash + (this.hspQseq != null ? this.hspQseq.hashCode() : 0); 079 hash = 67 * hash + (this.hspHseq != null ? this.hspHseq.hashCode() : 0); 080 hash = 67 * hash + (this.hspIdentityString != null ? this.hspIdentityString.hashCode() : 0); 081 return hash; 082 } 083 /** 084 * Experimental. 085 * Wants to implement conceptual comparisons of search results. 086 * Fields unrelated to search are deliberately not considered. 087 * 088 * In HSP case, alignment representation strings are considered. 089 * @return true if HSP alignments are the same, 090 * false otherwise or if alignment strings are undetermined 091 */ 092 @Override 093 public boolean equals(Object obj) { 094 if (obj == null) { 095 return false; 096 } 097 if (getClass() != obj.getClass()) { 098 return false; 099 } 100 final Hsp<?, ?> other = (Hsp<?, ?>) obj; 101 if ((this.hspQseq == null) ? (other.hspQseq != null) : !this.hspQseq.equals(other.hspQseq)) { 102 return false; 103 } 104 if ((this.hspHseq == null) ? (other.hspHseq != null) : !this.hspHseq.equals(other.hspHseq)) { 105 return false; 106 } 107 if ((this.hspIdentityString == null) ? (other.hspIdentityString != null) : !this.hspIdentityString.equals(other.hspIdentityString)) { 108 return false; 109 } 110 return true; 111 } 112 113 public SequencePair<S,C> getAlignment(){ 114 if (returnAln != null) return returnAln; 115 116 SimpleAlignedSequence<S,C> alignedQuery, alignedHit; 117 // queryFrom e hitTo? 118 int numBefore, numAfter; 119 120 alignedQuery = new SimpleAlignedSequence(getSequence(hspQseq), getAlignmentsSteps(hspQseq)); 121 alignedHit = new SimpleAlignedSequence(getSequence(hspHseq), getAlignmentsSteps(hspHseq)); 122 123 returnAln = new SimpleSequencePair<S, C>(alignedQuery, alignedHit); 124 125 return returnAln; 126 } 127 128 private Sequence getSequence(String gappedSequenceString){ 129 if (gappedSequenceString == null) return null; 130 131 Sequence returnSeq = null; 132 String sequenceString = gappedSequenceString.replace("-", ""); 133 134 try { 135 if (sequenceString.matches("^[ACTG]+$")) 136 returnSeq = new DNASequence(sequenceString, DNACompoundSet.getDNACompoundSet()); 137 else if (sequenceString.matches("^[ACUG]+$")) 138 returnSeq = new RNASequence(sequenceString, DNACompoundSet.getDNACompoundSet()); 139 else 140 returnSeq = new ProteinSequence(sequenceString, AminoAcidCompoundSet.getAminoAcidCompoundSet()); 141 } catch (CompoundNotFoundException ex) { 142 logger.error("Unexpected error, could not find compound when creating Sequence object from Hsp", ex); 143 } 144 return returnSeq; 145 } 146 147 private List<Step> getAlignmentsSteps(String gappedSequenceString){ 148 List<Step> returnList = new ArrayList<Step>(); 149 150 for (char c: gappedSequenceString.toCharArray()){ 151 if (c=='-') returnList.add(Step.GAP); else returnList.add(Step.COMPOUND); 152 } 153 return returnList; 154 } 155 156 public int getHspNum() { 157 return hspNum; 158 } 159 160 public double getHspBitScore() { 161 return hspBitScore; 162 } 163 164 public int getHspScore() { 165 return hspScore; 166 } 167 168 public double getHspEvalue() { 169 return hspEvalue; 170 } 171 172 public int getHspQueryFrom() { 173 return hspQueryFrom; 174 } 175 176 public int getHspQueryTo() { 177 return hspQueryTo; 178 } 179 180 public int getHspHitFrom() { 181 return hspHitFrom; 182 } 183 184 public int getHspHitTo() { 185 return hspHitTo; 186 } 187 188 public int getHspQueryFrame() { 189 return hspQueryFrame; 190 } 191 192 public int getHspHitFrame() { 193 return hspHitFrame; 194 } 195 196 public int getHspIdentity() { 197 return hspIdentity; 198 } 199 200 public int getHspPositive() { 201 return hspPositive; 202 } 203 204 public int getHspGaps() { 205 return hspGaps; 206 } 207 208 public int getHspAlignLen() { 209 return hspAlignLen; 210 } 211 /** 212 * HSP aligned query sequence string 213 * @return 214 */ 215 public String getHspQseq() { 216 return hspQseq; 217 } 218 /** 219 * HSP aligned hit sequence string 220 * @return 221 */ 222 public String getHspHseq() { 223 return hspHseq; 224 } 225 /** 226 * Identity string representing correspondence between aligned residues 227 * @return 228 */ 229 public String getHspIdentityString() { 230 return hspIdentityString; 231 } 232 233 public Double getPercentageIdentity() { 234 if (percentageIdentity != null) return percentageIdentity; 235 if (hspIdentity!= null && hspAlignLen != null) return (double)hspIdentity/hspAlignLen; 236 return null; 237 } 238 239 public Integer getMismatchCount() { 240 if (mismatchCount != null) return mismatchCount; 241 if (hspIdentity!= null && hspAlignLen != null) return hspIdentity-hspAlignLen; 242 return null; 243 } 244 245 public Hsp(int hspNum, double hspBitScore, int hspScore, double hspEvalue, int hspQueryFrom, int hspQueryTo, int hspHitFrom, int hspHitTo, int hspQueryFrame, int hspHitFrame, int hspIdentity, int hspPositive, int hspGaps, int hspAlignLen, String hspQseq, String hspHseq, String hspIdentityString, Double percentageIdentity, Integer mismatchCount) { 246 this.hspNum = hspNum; 247 this.hspBitScore = hspBitScore; 248 this.hspScore = hspScore; 249 this.hspEvalue = hspEvalue; 250 this.hspQueryFrom = hspQueryFrom; 251 this.hspQueryTo = hspQueryTo; 252 this.hspHitFrom = hspHitFrom; 253 this.hspHitTo = hspHitTo; 254 this.hspQueryFrame = hspQueryFrame; 255 this.hspHitFrame = hspHitFrame; 256 this.hspIdentity = hspIdentity; 257 this.hspPositive = hspPositive; 258 this.hspGaps = hspGaps; 259 this.hspIdentity = hspAlignLen; 260 this.hspQseq = hspQseq; 261 this.hspHseq = hspHseq; 262 this.hspIdentityString = hspIdentityString; 263 this.percentageIdentity = percentageIdentity; 264 this.mismatchCount = mismatchCount; 265 266 // sanity check 267 if (percentageIdentity != null && (percentageIdentity < 0 || percentageIdentity >1)) 268 throw new IllegalArgumentException("Percentage identity must be between 0 and 1"); 269 270 } 271 272}