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