2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 package jalview.datamodel;
24 import jalview.analysis.*;
35 SequenceI datasetSequence;
37 private char [] sequence;
45 /** This annotation is displayed below the alignment but the
46 * positions are tied to the residues of this sequence */
50 public SequenceFeature[] sequenceFeatures;
54 * Creates a new Sequence object.
56 * @param name DOCUMENT ME!
57 * @param sequence DOCUMENT ME!
58 * @param start DOCUMENT ME!
59 * @param end DOCUMENT ME!
61 public Sequence(String name, String sequence, int start, int end)
64 this.sequence = sequence.toCharArray();
71 public Sequence(String name, char [] sequence, int start, int end)
74 this.sequence = sequence;
81 com.stevesoft.pat.Regex limitrx = new com.stevesoft.pat.Regex(
82 "[/][0-9]{1,}[-][0-9]{1,}$");
83 com.stevesoft.pat.Regex endrx = new com.stevesoft.pat.Regex(
88 // Does sequence have the /start-end signiature?
89 if (limitrx.search(name))
91 name = limitrx.left();
92 endrx.search(limitrx.stringMatched());
93 setStart(Integer.parseInt(limitrx.stringMatched().substring(1,
94 endrx.matchedFrom() - 1)));
95 setEnd(Integer.parseInt(endrx.stringMatched()));
99 void checkValidRange()
104 for (int j = 0; j < sequence.length; j++)
106 if (!jalview.util.Comparison.isGap( sequence[j] ))
122 * Creates a new Sequence object.
124 * @param name DOCUMENT ME!
125 * @param sequence DOCUMENT ME!
127 public Sequence(String name, String sequence)
129 this(name, sequence, 1, -1);
133 * Creates a new Sequence object with new features, DBRefEntries, AlignmentAnnotations, and PDBIds
134 * but inherits any existing dataset sequence reference.
135 * @param seq DOCUMENT ME!
137 public Sequence(SequenceI seq)
143 description = seq.getDescription();
144 if (seq.getSequenceFeatures()!=null) {
145 SequenceFeature[] sf = seq.getSequenceFeatures();
146 for (int i=0; i<sf.length; i++) {
147 addSequenceFeature(new SequenceFeature(sf[i]));
150 if (seq.getDBRef()!=null) {
151 DBRefEntry[] dbr = seq.getDBRef();
152 for (int i=0; i<dbr.length; i++) {
153 addDBRef(new DBRefEntry(dbr[i]));
156 setDatasetSequence(seq.getDatasetSequence());
157 if (seq.getAnnotation()!=null) {
158 AlignmentAnnotation[] sqann = seq.getAnnotation();
159 for (int i=0;i<sqann.length; i++)
161 AlignmentAnnotation newann = new AlignmentAnnotation(sqann[i]);
162 addAlignmentAnnotation(newann);
165 if (seq.getPDBId()!=null) {
166 Vector ids = seq.getPDBId();
167 Enumeration e = ids.elements();
168 while (e.hasMoreElements()) {
169 this.addPDBId(new PDBEntry((PDBEntry) e.nextElement()));
178 * @param v DOCUMENT ME!
180 public void setSequenceFeatures(SequenceFeature[] features)
182 sequenceFeatures = features;
185 public synchronized void addSequenceFeature(SequenceFeature sf)
187 if (sequenceFeatures == null)
189 sequenceFeatures = new SequenceFeature[0];
192 for (int i = 0; i < sequenceFeatures.length; i++)
194 if (sequenceFeatures[i].equals(sf))
200 SequenceFeature[] temp = new SequenceFeature[sequenceFeatures.length + 1];
201 System.arraycopy(sequenceFeatures, 0, temp, 0, sequenceFeatures.length);
202 temp[sequenceFeatures.length] = sf;
204 sequenceFeatures = temp;
207 public void deleteFeature(SequenceFeature sf)
209 if(sequenceFeatures==null)
215 for (index = 0; index < sequenceFeatures.length; index++)
217 if (sequenceFeatures[index].equals(sf))
224 if(index==sequenceFeatures.length)
229 int sfLength = sequenceFeatures.length;
232 sequenceFeatures = null;
236 SequenceFeature[] temp = new SequenceFeature[sfLength-1];
237 System.arraycopy(sequenceFeatures, 0, temp, 0, index);
241 System.arraycopy(sequenceFeatures,
244 index, sequenceFeatures.length - index -1);
247 sequenceFeatures = temp;
254 * @return DOCUMENT ME!
256 public SequenceFeature[] getSequenceFeatures()
258 return sequenceFeatures;
261 public void addPDBId(PDBEntry entry)
265 pdbIds = new Vector();
268 pdbIds.addElement(entry);
274 * @param id DOCUMENT ME!
276 public void setPDBId(Vector id)
284 * @return DOCUMENT ME!
286 public Vector getPDBId()
294 * @return DOCUMENT ME!
296 public String getDisplayId(boolean jvsuffix)
298 StringBuffer result = new StringBuffer(name);
301 result.append("/" + start + "-" + end);
304 return result.toString();
310 * @param name DOCUMENT ME!
312 public void setName(String name)
321 * @return DOCUMENT ME!
323 public String getName()
331 * @param start DOCUMENT ME!
333 public void setStart(int start)
341 * @return DOCUMENT ME!
343 public int getStart()
351 * @param end DOCUMENT ME!
353 public void setEnd(int end)
361 * @return DOCUMENT ME!
371 * @return DOCUMENT ME!
373 public int getLength()
375 return this.sequence.length;
381 * @param seq DOCUMENT ME!
383 public void setSequence(String seq)
385 this.sequence = seq.toCharArray();
390 public String getSequenceAsString()
392 return new String(sequence);
395 public String getSequenceAsString(int start, int end)
397 return new String(getSequence(start, end));
401 public char [] getSequence()
409 * @param start DOCUMENT ME!
410 * @param end DOCUMENT ME!
412 * @return DOCUMENT ME!
414 public char [] getSequence(int start, int end)
416 // JBPNote - left to user to pad the result here (TODO:Decide on this policy)
417 if (start >= sequence.length)
422 if (end >= sequence.length)
424 end = sequence.length;
427 char [] reply = new char[end-start];
428 System.arraycopy(sequence, start, reply, 0, end-start);
435 * make a new Sequence object from start to end (including gaps) over this seqeunce
440 public SequenceI getSubSequence(int start, int end)
446 char [] seq = getSequence(start, end);
451 int nstart = findPosition(start);
452 int nend = findPosition(end) - 1;
453 // JBPNote - this is an incomplete copy.
454 SequenceI nseq = new Sequence(this.getName(), seq, nstart, nend);
455 nseq.setDescription(description);
456 if (datasetSequence!=null)
458 nseq.setDatasetSequence(datasetSequence);
462 nseq.setDatasetSequence(this);
470 * @param i DOCUMENT ME!
472 * @return DOCUMENT ME!
474 public char getCharAt(int i)
476 if (i < sequence.length)
489 * @param desc DOCUMENT ME!
491 public void setDescription(String desc)
493 this.description = desc;
499 * @return DOCUMENT ME!
501 public String getDescription()
503 return this.description;
507 * Return the alignment position for a sequence position
509 * @param pos lying from start to end
511 * @return aligned position of residue pos
513 public int findIndex(int pos)
515 // returns the alignment position for a residue
519 while ( (i < sequence.length) && (j <= end) && (j <= pos))
521 if (!jalview.util.Comparison.isGap(sequence[i]))
529 if ( (j == end) && (j < pos))
540 * Returns the sequence position for an alignment position
542 * @param i column index in alignment (from 1)
544 * @return residue number for residue (left of and) nearest ith column
546 public int findPosition(int i)
550 int seqlen = sequence.length;
551 while ( (j < i) && (j < seqlen))
553 if (!jalview.util.Comparison.isGap( sequence[j] ))
565 * Returns an int array where indices correspond to each residue in the sequence and the element value gives its position in the alignment
567 * @return int[SequenceI.getEnd()-SequenceI.getStart()+1] or null if no residues in SequenceI object
569 public int[] gapMap()
571 String seq = jalview.analysis.AlignSeq.extractGaps(jalview.util.Comparison.
572 GapChars, new String(sequence));
573 int[] map = new int[seq.length()];
577 while (j < sequence.length)
579 if (!jalview.util.Comparison.isGap(sequence[j]))
593 * @param i DOCUMENT ME!
594 * @param j DOCUMENT ME!
596 public void deleteChars(int i, int j)
598 if (i >= sequence.length)
605 if (j >= sequence.length)
608 System.arraycopy(sequence,0,tmp,0,i);
612 tmp = new char[sequence.length-j+i];
613 System.arraycopy(sequence,0,tmp,0,i);
614 System.arraycopy(sequence,j,tmp,i,sequence.length-j);
617 if (this.datasetSequence != null)
619 for (int s = i; s < j; s++)
621 if (jalview.schemes.ResidueProperties.aaIndex[sequence[s]] != 23)
624 Sequence ds = new Sequence(name,
625 AlignSeq.extractGaps(
626 jalview.util.Comparison.GapChars,
627 this.getSequenceAsString()
631 ds.setDescription(description);
645 * @param i DOCUMENT ME!
646 * @param c DOCUMENT ME!
647 * @param chop DOCUMENT ME!
649 public void insertCharAt(int i, int length, char c)
651 char [] tmp = new char[sequence.length+length];
653 if (i >= sequence.length)
655 System.arraycopy(sequence, 0, tmp, 0, sequence.length);
660 System.arraycopy(sequence, 0, tmp, 0, i);
671 if (i < sequence.length)
673 System.arraycopy(sequence, i, tmp, index, sequence.length-i );
679 public void insertCharAt(int i, char c)
681 insertCharAt(i, 1, c);
684 public String getVamsasId()
689 public void setVamsasId(String id)
694 public void setDBRef(DBRefEntry[] dbref)
699 public DBRefEntry[] getDBRef()
704 public void addDBRef(DBRefEntry entry)
708 dbrefs = new DBRefEntry[0];
711 int i, iSize = dbrefs.length;
713 for(i=0; i<iSize; i++)
715 if(dbrefs[i].equals(entry))
721 DBRefEntry[] temp = new DBRefEntry[iSize + 1];
722 System.arraycopy(dbrefs, 0, temp, 0, iSize);
723 temp[temp.length - 1] = entry;
728 public void setDatasetSequence(SequenceI seq)
730 datasetSequence = seq;
733 public SequenceI getDatasetSequence()
735 return datasetSequence;
738 public AlignmentAnnotation[] getAnnotation()
740 if (annotation == null)
745 AlignmentAnnotation[] ret = new AlignmentAnnotation[annotation.size()];
746 for (int r = 0; r < ret.length; r++)
748 ret[r] = (AlignmentAnnotation) annotation.elementAt(r);
754 public void addAlignmentAnnotation(AlignmentAnnotation annotation)
756 if (this.annotation == null)
758 this.annotation = new Vector();
761 this.annotation.addElement(annotation);
762 annotation.setSequenceRef(this);
767 * test if this is a valid candidate for another
768 * sequence's dataset sequence.
771 private boolean isValidDatasetSequence()
773 if (datasetSequence!=null)
777 for (int i=0;i<sequence.length; i++)
779 if (jalview.util.Comparison.isGap(sequence[i]))
787 * @see jalview.datamodel.SequenceI#deriveSequence()
789 public SequenceI deriveSequence()
791 SequenceI seq=new Sequence(this);
792 if (datasetSequence != null)
794 // duplicate current sequence with same dataset
795 seq.setDatasetSequence(datasetSequence);
799 if (isValidDatasetSequence())
801 // Use this as dataset sequence
802 seq.setDatasetSequence(this);
804 // Create a new, valid dataset sequence
806 ds.setSequence(AlignSeq.extractGaps(jalview.util.Comparison.GapChars, new String(sequence)));
807 setDatasetSequence(ds);
808 seq = this; // and return this sequence as the derived sequence.
814 * @see jalview.datamodel.SequenceI#setAlignmentAnnotation(AlignmmentAnnotation[] annotations)
816 public void setAlignmentAnnotation(AlignmentAnnotation[] annotations)
818 if (annotation!=null) {
819 annotation.removeAllElements();
821 if (annotations!=null) {
822 for (int i=0; i<annotations.length; i++)
824 if (annotations[i]!=null)
825 addAlignmentAnnotation(annotations[i]);