JAL-2437 Fixed reordering of sequences when hiding and revealing
[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 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 License for more details.
16  * 
17  * You should have received a copy of the GNU General 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   /**
362    * Compact representation of alignment
363    * 
364    * @return CigarArray
365    */
366   CigarArray getCompactAlignment();
367
368   /**
369    * Set an arbitrary key value pair for an alignment. Note: both key and value
370    * objects should return a meaningful, human readable response to .toString()
371    * 
372    * @param key
373    * @param value
374    */
375   void setProperty(Object key, Object value);
376
377   /**
378    * Get a named property from the alignment.
379    * 
380    * @param key
381    * @return value of property
382    */
383   Object getProperty(Object key);
384
385   /**
386    * Get the property hashtable.
387    * 
388    * @return hashtable of alignment properties (or null if none are defined)
389    */
390   Hashtable getProperties();
391
392   /**
393    * add a reference to a frame of aligned codons for this alignment
394    * 
395    * @param codons
396    */
397   void addCodonFrame(AlignedCodonFrame codons);
398
399   /**
400    * remove a particular codon frame reference from this alignment
401    * 
402    * @param codons
403    * @return true if codon frame was removed.
404    */
405   boolean removeCodonFrame(AlignedCodonFrame codons);
406
407   /**
408    * get all codon frames associated with this alignment
409    * 
410    * @return
411    */
412   List<AlignedCodonFrame> getCodonFrames();
413
414   /**
415    * Set the codon frame mappings (replacing any existing list).
416    */
417   void setCodonFrames(List<AlignedCodonFrame> acfs);
418
419   /**
420    * get codon frames involving sequenceI
421    */
422   List<AlignedCodonFrame> getCodonFrame(SequenceI seq);
423
424   /**
425    * find sequence with given name in alignment
426    * 
427    * @param token
428    *          name to find
429    * @param b
430    *          true implies that case insensitive matching will <em>also</em> be
431    *          tried
432    * @return matched sequence or null
433    */
434   SequenceI findName(String token, boolean b);
435
436   /**
437    * find next sequence with given name in alignment starting after a given
438    * sequence
439    * 
440    * @param startAfter
441    *          the sequence after which the search will be started (usually the
442    *          result of the last call to findName)
443    * @param token
444    *          name to find
445    * @param b
446    *          true implies that case insensitive matching will <em>also</em> be
447    *          tried
448    * @return matched sequence or null
449    */
450   SequenceI findName(SequenceI startAfter, String token, boolean b);
451
452   /**
453    * find first sequence in alignment which is involved in the given search
454    * result object
455    * 
456    * @param results
457    * @return -1 or index of sequence in alignment
458    */
459   int findIndex(SearchResultsI results);
460
461   /**
462    * append sequences and annotation from another alignment object to this one.
463    * Note: this is a straight transfer of object references, and may result in
464    * toappend's dependent data being transformed to fit the alignment (changing
465    * gap characters, etc...). If you are uncertain, use the copy Alignment copy
466    * constructor to create a new version which can be appended without side
467    * effect.
468    * 
469    * @param toappend
470    *          - the alignment to be appended.
471    */
472   void append(AlignmentI toappend);
473
474   /**
475    * Justify the sequences to the left or right by deleting and inserting gaps
476    * before the initial residue or after the terminal residue
477    * 
478    * @param right
479    *          true if alignment padded to right, false to justify to left
480    * @return true if alignment was changed TODO: return undo object
481    */
482   boolean justify(boolean right);
483
484   /**
485    * add given annotation row at given position (0 is start, -1 is end)
486    * 
487    * @param consensus
488    * @param i
489    */
490   void addAnnotation(AlignmentAnnotation consensus, int i);
491
492   /**
493    * search for or create a specific annotation row on the alignment
494    * 
495    * @param name
496    *          name for annotation (must match)
497    * @param calcId
498    *          calcId for the annotation (null or must match)
499    * @param autoCalc
500    *          - value of autocalc flag for the annotation
501    * @param seqRef
502    *          - null or specific sequence reference
503    * @param groupRef
504    *          - null or specific group reference
505    * @param method
506    *          - CalcId for the annotation (must match)
507    * 
508    * @return existing annotation matching the given attributes
509    */
510   AlignmentAnnotation findOrCreateAnnotation(String name, String calcId,
511           boolean autoCalc, SequenceI seqRef, SequenceGroup groupRef);
512
513   /**
514    * move the given group up or down in the alignment by the given number of
515    * rows. Implementor assumes given group is already present on alignment - no
516    * recalculations are triggered.
517    * 
518    * @param sg
519    * @param map
520    * @param up
521    * @param i
522    */
523   void moveSelectedSequencesByOne(SequenceGroup sg,
524           Map<SequenceI, SequenceCollectionI> map, boolean up);
525
526   /**
527    * validate annotation after an edit and update any alignment state flags
528    * accordingly
529    * 
530    * @param alignmentAnnotation
531    */
532   void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
533
534   /**
535    * Align this alignment the same as the given one. If both of the same type
536    * (nucleotide/protein) then align both identically. If this is nucleotide and
537    * the other is protein, make 3 gaps for each gap in the protein sequences. If
538    * this is protein and the other is nucleotide, insert a gap for each 3 gaps
539    * (or part thereof) between nucleotide bases. Returns the number of mapped
540    * sequences that were realigned .
541    * 
542    * @param al
543    * @return
544    */
545   int alignAs(AlignmentI al);
546
547   /**
548    * Returns the set of distinct sequence names in the alignment.
549    * 
550    * @return
551    */
552   Set<String> getSequenceNames();
553
554   /**
555    * Checks if the alignment has at least one sequence with one non-gaped
556    * residue
557    * 
558    * @return
559    */
560   public boolean hasValidSequence();
561
562   /**
563    * Update any mappings to 'virtual' sequences to compatible real ones, if
564    * present in the added sequences. Returns a count of mappings updated.
565    * 
566    * @param seqs
567    * @return
568    */
569   int realiseMappings(List<SequenceI> seqs);
570
571   /**
572    * Returns the first AlignedCodonFrame that has a mapping between the given
573    * dataset sequences
574    * 
575    * @param mapFrom
576    * @param mapTo
577    * @return
578    */
579   AlignedCodonFrame getMapping(SequenceI mapFrom, SequenceI mapTo);
580
581   /**
582    * Calculate the visible start and end index of an alignment. The result is
583    * returned an int array where: int[0] = startIndex, and int[1] = endIndex.
584    * 
585    * @param hiddenCols
586    * @return
587    */
588   public int[] getVisibleStartAndEndIndex(List<int[]> hiddenCols);
589
590 }