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