Merge branch 'bug/JAL-2920_uniprotvariantfeature' into releases/Release_2_10_4_Branch
[jalview.git] / src / jalview / datamodel / AlignmentI.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.datamodel;
22
23 import java.util.Hashtable;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 /**
29  * Data structure to hold and manipulate a multiple sequence alignment
30  */
31 public interface AlignmentI extends AnnotatedCollectionI
32 {
33   /**
34    * Calculates the number of sequences in an alignment, excluding hidden
35    * sequences
36    * 
37    * @return Number of sequences in alignment
38    */
39   int getHeight();
40
41   /**
42    * Calculates the number of sequences in an alignment, including hidden
43    * sequences
44    * 
45    * @return Number of sequences in alignment
46    */
47   int getAbsoluteHeight();
48
49   /**
50    * 
51    * Calculates the maximum width of the alignment, including gaps.
52    * 
53    * @return Greatest sequence length within alignment, or -1 if no sequences
54    *         present
55    */
56   @Override
57   int getWidth();
58
59   /**
60    * Calculates if this set of sequences (visible and invisible) are all the
61    * same length
62    * 
63    * @return true if all sequences in alignment are the same length
64    */
65   boolean isAligned();
66
67   /**
68    * Calculates if this set of sequences is all the same length
69    * 
70    * @param includeHidden
71    *          optionally exclude hidden sequences from test
72    * @return true if all (or just visible) sequences are the same length
73    */
74   boolean isAligned(boolean includeHidden);
75
76   /**
77    * Answers if the sequence at alignmentIndex is hidden
78    * 
79    * @param alignmentIndex
80    *          the index to check
81    * @return true if the sequence is hidden
82    */
83   boolean isHidden(int alignmentIndex);
84
85   /**
86    * Gets sequences as a Synchronized collection
87    * 
88    * @return All sequences in alignment.
89    */
90   @Override
91   List<SequenceI> getSequences();
92
93   /**
94    * Gets sequences as a SequenceI[]
95    * 
96    * @return All sequences in alignment.
97    */
98   SequenceI[] getSequencesArray();
99
100   /**
101    * Find a specific sequence in this alignment.
102    * 
103    * @param i
104    *          Index of required sequence.
105    * 
106    * @return SequenceI at given index.
107    */
108   SequenceI getSequenceAt(int i);
109
110   /**
111    * Find a specific sequence in this alignment.
112    * 
113    * @param i
114    *          Index of required sequence in full alignment, i.e. if all columns
115    *          were visible
116    * 
117    * @return SequenceI at given index.
118    */
119   SequenceI getSequenceAtAbsoluteIndex(int i);
120
121   /**
122    * Returns a map of lists of sequences keyed by sequence name.
123    * 
124    * @return
125    */
126   Map<String, List<SequenceI>> getSequencesByName();
127
128   /**
129    * Add a new sequence to this alignment.
130    * 
131    * @param seq
132    *          New sequence will be added at end of alignment.
133    */
134   void addSequence(SequenceI seq);
135
136   /**
137    * Used to set a particular index of the alignment with the given sequence.
138    * 
139    * @param i
140    *          Index of sequence to be updated. if i>length, sequence will be
141    *          added to end, with no intervening positions.
142    * @param seq
143    *          New sequence to be inserted. The existing sequence at position i
144    *          will be replaced.
145    * @return existing sequence (or null if i>current length)
146    */
147   SequenceI replaceSequenceAt(int i, SequenceI seq);
148
149   /**
150    * Deletes a sequence from the alignment. Updates hidden sequences to account
151    * for the removed sequence. Do NOT use this method to delete sequences which
152    * are just hidden.
153    * 
154    * @param s
155    *          Sequence to be deleted.
156    */
157   void deleteSequence(SequenceI s);
158
159   /**
160    * Deletes a sequence from the alignment. Updates hidden sequences to account
161    * for the removed sequence. Do NOT use this method to delete sequences which
162    * are just hidden.
163    * 
164    * @param i
165    *          Index of sequence to be deleted.
166    */
167   void deleteSequence(int i);
168
169   /**
170    * Deletes a sequence in the alignment which has been hidden.
171    * 
172    * @param i
173    *          Index of sequence to be deleted
174    */
175   void deleteHiddenSequence(int i);
176
177   /**
178    * Finds sequence in alignment using sequence name as query.
179    * 
180    * @param name
181    *          Id of sequence to search for.
182    * 
183    * @return Sequence matching query, if found. If not found returns null.
184    */
185   SequenceI findName(String name);
186
187   SequenceI[] findSequenceMatch(String name);
188
189   /**
190    * Finds index of a given sequence in the alignment.
191    * 
192    * @param s
193    *          Sequence to look for.
194    * 
195    * @return Index of sequence within the alignment or -1 if not found
196    */
197   int findIndex(SequenceI s);
198
199   /**
200    * Returns the first group (in the order in which groups were added) that
201    * includes the given sequence instance and aligned position (base 0), or null
202    * if none found
203    * 
204    * @param seq
205    *          - must be contained in the alignment (not a dataset sequence)
206    * @param position
207    * 
208    * @return
209    */
210   SequenceGroup findGroup(SequenceI seq, int position);
211
212   /**
213    * Finds all groups that a given sequence is part of.
214    * 
215    * @param s
216    *          Sequence in alignment.
217    * 
218    * @return All groups containing given sequence.
219    */
220   SequenceGroup[] findAllGroups(SequenceI s);
221
222   /**
223    * Adds a new SequenceGroup to this alignment.
224    * 
225    * @param sg
226    *          New group to be added.
227    */
228   void addGroup(SequenceGroup sg);
229
230   /**
231    * Deletes a specific SequenceGroup
232    * 
233    * @param g
234    *          Group will be deleted from alignment.
235    */
236   void deleteGroup(SequenceGroup g);
237
238   /**
239    * Get all the groups associated with this alignment.
240    * 
241    * @return All groups as a list.
242    */
243   List<SequenceGroup> getGroups();
244
245   /**
246    * Deletes all groups from this alignment.
247    */
248   void deleteAllGroups();
249
250   /**
251    * Adds a new AlignmentAnnotation to this alignment
252    * 
253    * @note Care should be taken to ensure that annotation is at least as wide as
254    *       the longest sequence in the alignment for rendering purposes.
255    */
256   void addAnnotation(AlignmentAnnotation aa);
257
258   /**
259    * moves annotation to a specified index in alignment annotation display stack
260    * 
261    * @param aa
262    *          the annotation object to be moved
263    * @param index
264    *          the destination position
265    */
266   void setAnnotationIndex(AlignmentAnnotation aa, int index);
267
268   /**
269    * Delete all annotations, including auto-calculated if the flag is set true.
270    * Returns true if at least one annotation was deleted, else false.
271    * 
272    * @param includingAutoCalculated
273    * @return
274    */
275   boolean deleteAllAnnotations(boolean includingAutoCalculated);
276
277   /**
278    * Deletes a specific AlignmentAnnotation from the alignment, and removes its
279    * reference from any SequenceI or SequenceGroup object's annotation if and
280    * only if aa is contained within the alignment's annotation vector.
281    * Otherwise, it will do nothing.
282    * 
283    * @param aa
284    *          the annotation to delete
285    * @return true if annotation was deleted from this alignment.
286    */
287   boolean deleteAnnotation(AlignmentAnnotation aa);
288
289   /**
290    * Deletes a specific AlignmentAnnotation from the alignment, and optionally
291    * removes any reference from any SequenceI or SequenceGroup object's
292    * annotation if and only if aa is contained within the alignment's annotation
293    * vector. Otherwise, it will do nothing.
294    * 
295    * @param aa
296    *          the annotation to delete
297    * @param unhook
298    *          flag indicating if any references should be removed from
299    *          annotation - use this if you intend to add the annotation back
300    *          into the alignment
301    * @return true if annotation was deleted from this alignment.
302    */
303   boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
304
305   /**
306    * Get the annotation associated with this alignment (this can be null if no
307    * annotation has ever been created on the alignment)
308    * 
309    * @return array of AlignmentAnnotation objects
310    */
311   @Override
312   AlignmentAnnotation[] getAlignmentAnnotation();
313
314   /**
315    * Change the gap character used in this alignment to 'gc'
316    * 
317    * @param gc
318    *          the new gap character.
319    */
320   void setGapCharacter(char gc);
321
322   /**
323    * Get the gap character used in this alignment
324    * 
325    * @return gap character
326    */
327   char getGapCharacter();
328
329   /**
330    * Test if alignment contains RNA structure
331    * 
332    * @return true if RNA structure AligmnentAnnotation was added to alignment
333    */
334   boolean hasRNAStructure();
335
336   /**
337    * Get the associated dataset for the alignment.
338    * 
339    * @return Alignment containing dataset sequences or null of this is a
340    *         dataset.
341    */
342   AlignmentI getDataset();
343
344   /**
345    * Set the associated dataset for the alignment, or create one.
346    * 
347    * @param dataset
348    *          The dataset alignment or null to construct one.
349    */
350   void setDataset(AlignmentI dataset);
351
352   /**
353    * pads sequences with gaps (to ensure the set looks like an alignment)
354    * 
355    * @return boolean true if alignment was modified
356    */
357   boolean padGaps();
358
359   HiddenSequences getHiddenSequences();
360
361   HiddenColumns getHiddenColumns();
362
363   /**
364    * Compact representation of alignment
365    * 
366    * @return CigarArray
367    */
368   CigarArray getCompactAlignment();
369
370   /**
371    * Set an arbitrary key value pair for an alignment. Note: both key and value
372    * objects should return a meaningful, human readable response to .toString()
373    * 
374    * @param key
375    * @param value
376    */
377   void setProperty(Object key, Object value);
378
379   /**
380    * Get a named property from the alignment.
381    * 
382    * @param key
383    * @return value of property
384    */
385   Object getProperty(Object key);
386
387   /**
388    * Get the property hashtable.
389    * 
390    * @return hashtable of alignment properties (or null if none are defined)
391    */
392   Hashtable getProperties();
393
394   /**
395    * add a reference to a frame of aligned codons for this alignment
396    * 
397    * @param codons
398    */
399   void addCodonFrame(AlignedCodonFrame codons);
400
401   /**
402    * remove a particular codon frame reference from this alignment
403    * 
404    * @param codons
405    * @return true if codon frame was removed.
406    */
407   boolean removeCodonFrame(AlignedCodonFrame codons);
408
409   /**
410    * get all codon frames associated with this alignment
411    * 
412    * @return
413    */
414   List<AlignedCodonFrame> getCodonFrames();
415
416   /**
417    * Set the codon frame mappings (replacing any existing list).
418    */
419   void setCodonFrames(List<AlignedCodonFrame> acfs);
420
421   /**
422    * get codon frames involving sequenceI
423    */
424   List<AlignedCodonFrame> getCodonFrame(SequenceI seq);
425
426   /**
427    * find sequence with given name in alignment
428    * 
429    * @param token
430    *          name to find
431    * @param b
432    *          true implies that case insensitive matching will <em>also</em> be
433    *          tried
434    * @return matched sequence or null
435    */
436   SequenceI findName(String token, boolean b);
437
438   /**
439    * find next sequence with given name in alignment starting after a given
440    * sequence
441    * 
442    * @param startAfter
443    *          the sequence after which the search will be started (usually the
444    *          result of the last call to findName)
445    * @param token
446    *          name to find
447    * @param b
448    *          true implies that case insensitive matching will <em>also</em> be
449    *          tried
450    * @return matched sequence or null
451    */
452   SequenceI findName(SequenceI startAfter, String token, boolean b);
453
454   /**
455    * find first sequence in alignment which is involved in the given search
456    * result object
457    * 
458    * @param results
459    * @return -1 or index of sequence in alignment
460    */
461   int findIndex(SearchResultsI results);
462
463   /**
464    * append sequences and annotation from another alignment object to this one.
465    * Note: this is a straight transfer of object references, and may result in
466    * toappend's dependent data being transformed to fit the alignment (changing
467    * gap characters, etc...). If you are uncertain, use the copy Alignment copy
468    * constructor to create a new version which can be appended without side
469    * effect.
470    * 
471    * @param toappend
472    *          - the alignment to be appended.
473    */
474   void append(AlignmentI toappend);
475
476   /**
477    * Justify the sequences to the left or right by deleting and inserting gaps
478    * before the initial residue or after the terminal residue
479    * 
480    * @param right
481    *          true if alignment padded to right, false to justify to left
482    * @return true if alignment was changed TODO: return undo object
483    */
484   boolean justify(boolean right);
485
486   /**
487    * add given annotation row at given position (0 is start, -1 is end)
488    * 
489    * @param consensus
490    * @param i
491    */
492   void addAnnotation(AlignmentAnnotation consensus, int i);
493
494   /**
495    * search for or create a specific annotation row on the alignment
496    * 
497    * @param name
498    *          name for annotation (must match)
499    * @param calcId
500    *          calcId for the annotation (null or must match)
501    * @param autoCalc
502    *          - value of autocalc flag for the annotation
503    * @param seqRef
504    *          - null or specific sequence reference
505    * @param groupRef
506    *          - null or specific group reference
507    * @param method
508    *          - CalcId for the annotation (must match)
509    * 
510    * @return existing annotation matching the given attributes
511    */
512   AlignmentAnnotation findOrCreateAnnotation(String name, String calcId,
513           boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef);
514
515   /**
516    * move the given group up or down in the alignment by the given number of
517    * rows. Implementor assumes given group is already present on alignment - no
518    * recalculations are triggered.
519    * 
520    * @param sg
521    * @param map
522    * @param up
523    * @param i
524    */
525   void moveSelectedSequencesByOne(SequenceGroup sg,
526           Map<SequenceI, SequenceCollectionI> map, boolean up);
527
528   /**
529    * validate annotation after an edit and update any alignment state flags
530    * accordingly
531    * 
532    * @param alignmentAnnotation
533    */
534   void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
535
536   /**
537    * Align this alignment the same as the given one. If both of the same type
538    * (nucleotide/protein) then align both identically. If this is nucleotide and
539    * the other is protein, make 3 gaps for each gap in the protein sequences. If
540    * this is protein and the other is nucleotide, insert a gap for each 3 gaps
541    * (or part thereof) between nucleotide bases. Returns the number of mapped
542    * sequences that were realigned .
543    * 
544    * @param al
545    * @return
546    */
547   int alignAs(AlignmentI al);
548
549   /**
550    * Returns the set of distinct sequence names in the alignment.
551    * 
552    * @return
553    */
554   Set<String> getSequenceNames();
555
556   /**
557    * Checks if the alignment has at least one sequence with one non-gaped
558    * residue
559    * 
560    * @return
561    */
562   public boolean hasValidSequence();
563
564   /**
565    * Update any mappings to 'virtual' sequences to compatible real ones, if
566    * present in the added sequences. Returns a count of mappings updated.
567    * 
568    * @param seqs
569    * @return
570    */
571   int realiseMappings(List<SequenceI> seqs);
572
573   /**
574    * Returns the first AlignedCodonFrame that has a mapping between the given
575    * dataset sequences
576    * 
577    * @param mapFrom
578    * @param mapTo
579    * @return
580    */
581   AlignedCodonFrame getMapping(SequenceI mapFrom, SequenceI mapTo);
582
583   /**
584    * Set the hidden columns collection on the alignment
585    * 
586    * @param cols
587    */
588   public void setHiddenColumns(HiddenColumns cols);
589
590   /**
591    * Set the first sequence as representative and hide its insertions. Typically
592    * used when loading JPred files.
593    */
594   public void setupJPredAlignment();
595
596   /**
597    * Add gaps into the sequences aligned to profileseq under the given
598    * AlignmentView
599    * 
600    * @param profileseq
601    *          sequence in al which sequences are aligned to
602    * @param input
603    *          alignment view where sequence corresponding to profileseq is first
604    *          entry
605    * @return new HiddenColumns for new alignment view, with insertions into
606    *         profileseq marked as hidden.
607    */
608   public HiddenColumns propagateInsertions(SequenceI profileseq,
609           AlignmentView input);
610
611 }