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