Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
AlignmentViewport | 91 | 790 | 479 |
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.viewmodel; | |
22 | ||
23 | import java.awt.Color; | |
24 | import java.beans.PropertyChangeSupport; | |
25 | import java.util.ArrayDeque; | |
26 | import java.util.ArrayList; | |
27 | import java.util.BitSet; | |
28 | import java.util.Deque; | |
29 | import java.util.HashMap; | |
30 | import java.util.Hashtable; | |
31 | import java.util.Iterator; | |
32 | import java.util.List; | |
33 | import java.util.Map; | |
34 | ||
35 | import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; | |
36 | import jalview.analysis.AlignmentUtils; | |
37 | import jalview.analysis.Conservation; | |
38 | import jalview.analysis.TreeModel; | |
39 | import jalview.api.AlignCalcManagerI; | |
40 | import jalview.api.AlignExportSettingsI; | |
41 | import jalview.api.AlignViewportI; | |
42 | import jalview.api.AlignmentViewPanel; | |
43 | import jalview.api.FeaturesDisplayedI; | |
44 | import jalview.api.ViewStyleI; | |
45 | import jalview.bin.Console; | |
46 | import jalview.commands.CommandI; | |
47 | import jalview.datamodel.AlignedCodonFrame; | |
48 | import jalview.datamodel.AlignmentAnnotation; | |
49 | import jalview.datamodel.AlignmentExportData; | |
50 | import jalview.datamodel.AlignmentI; | |
51 | import jalview.datamodel.AlignmentView; | |
52 | import jalview.datamodel.Annotation; | |
53 | import jalview.datamodel.ColumnSelection; | |
54 | import jalview.datamodel.ContactListI; | |
55 | import jalview.datamodel.ContactMatrixI; | |
56 | import jalview.datamodel.HiddenColumns; | |
57 | import jalview.datamodel.HiddenSequences; | |
58 | import jalview.datamodel.ProfilesI; | |
59 | import jalview.datamodel.SearchResultsI; | |
60 | import jalview.datamodel.Sequence; | |
61 | import jalview.datamodel.SequenceCollectionI; | |
62 | import jalview.datamodel.SequenceGroup; | |
63 | import jalview.datamodel.SequenceI; | |
64 | import jalview.gui.QuitHandler; | |
65 | import jalview.project.Jalview2XML; | |
66 | import jalview.renderer.ResidueShader; | |
67 | import jalview.renderer.ResidueShaderI; | |
68 | import jalview.schemes.ColourSchemeI; | |
69 | import jalview.structure.CommandListener; | |
70 | import jalview.structure.StructureSelectionManager; | |
71 | import jalview.structure.VamsasSource; | |
72 | import jalview.util.Comparison; | |
73 | import jalview.util.Constants; | |
74 | import jalview.util.MapList; | |
75 | import jalview.util.MappingUtils; | |
76 | import jalview.util.MessageManager; | |
77 | import jalview.viewmodel.styles.ViewStyle; | |
78 | import jalview.workers.AlignCalcManager; | |
79 | import jalview.workers.ComplementConsensusThread; | |
80 | import jalview.workers.ConsensusThread; | |
81 | import jalview.workers.SecondaryStructureConsensusThread; | |
82 | import jalview.workers.StrucConsensusThread; | |
83 | ||
84 | /** | |
85 | * base class holding visualization and analysis attributes and common logic for | |
86 | * an active alignment view displayed in the GUI | |
87 | * | |
88 | * @author jimp | |
89 | * | |
90 | */ | |
91 | public abstract class AlignmentViewport | |
92 | implements AlignViewportI, CommandListener, VamsasSource | |
93 | { | |
94 | protected ViewportRanges ranges; | |
95 | ||
96 | protected ViewStyleI viewStyle = new ViewStyle(); | |
97 | ||
98 | /** | |
99 | * A viewport that hosts the cDna view of this (protein), or vice versa (if | |
100 | * set). | |
101 | */ | |
102 | AlignViewportI codingComplement = null; | |
103 | ||
104 | FeaturesDisplayedI featuresDisplayed = null; | |
105 | ||
106 | protected Deque<CommandI> historyList = new ArrayDeque<>(); | |
107 | ||
108 | protected Deque<CommandI> redoList = new ArrayDeque<>(); | |
109 | ||
110 | /** | |
111 | * used to determine if quit should be confirmed | |
112 | */ | |
113 | private boolean savedUpToDate = false; | |
114 | ||
115 | /** | |
116 | * alignment displayed in the viewport. Please use get/setter | |
117 | */ | |
118 | protected AlignmentI alignment; | |
119 | ||
120 | 508 | public AlignmentViewport(AlignmentI al) |
121 | { | |
122 | 508 | setAlignment(al); |
123 | 508 | ranges = new ViewportRanges(al); |
124 | } | |
125 | ||
126 | /** | |
127 | * @param name | |
128 | * @see jalview.api.ViewStyleI#setFontName(java.lang.String) | |
129 | */ | |
130 | 0 | @Override |
131 | public void setFontName(String name) | |
132 | { | |
133 | 0 | viewStyle.setFontName(name); |
134 | } | |
135 | ||
136 | /** | |
137 | * @param style | |
138 | * @see jalview.api.ViewStyleI#setFontStyle(int) | |
139 | */ | |
140 | 0 | @Override |
141 | public void setFontStyle(int style) | |
142 | { | |
143 | 0 | viewStyle.setFontStyle(style); |
144 | } | |
145 | ||
146 | /** | |
147 | * @param size | |
148 | * @see jalview.api.ViewStyleI#setFontSize(int) | |
149 | */ | |
150 | 0 | @Override |
151 | public void setFontSize(int size) | |
152 | { | |
153 | 0 | viewStyle.setFontSize(size); |
154 | } | |
155 | ||
156 | /** | |
157 | * @return | |
158 | * @see jalview.api.ViewStyleI#getFontStyle() | |
159 | */ | |
160 | 0 | @Override |
161 | public int getFontStyle() | |
162 | { | |
163 | 0 | return viewStyle.getFontStyle(); |
164 | } | |
165 | ||
166 | /** | |
167 | * @return | |
168 | * @see jalview.api.ViewStyleI#getFontName() | |
169 | */ | |
170 | 0 | @Override |
171 | public String getFontName() | |
172 | { | |
173 | 0 | return viewStyle.getFontName(); |
174 | } | |
175 | ||
176 | /** | |
177 | * @return | |
178 | * @see jalview.api.ViewStyleI#getFontSize() | |
179 | */ | |
180 | 0 | @Override |
181 | public int getFontSize() | |
182 | { | |
183 | 0 | return viewStyle.getFontSize(); |
184 | } | |
185 | ||
186 | /** | |
187 | * @param upperCasebold | |
188 | * @see jalview.api.ViewStyleI#setUpperCasebold(boolean) | |
189 | */ | |
190 | 0 | @Override |
191 | public void setUpperCasebold(boolean upperCasebold) | |
192 | { | |
193 | 0 | viewStyle.setUpperCasebold(upperCasebold); |
194 | } | |
195 | ||
196 | /** | |
197 | * @return | |
198 | * @see jalview.api.ViewStyleI#isUpperCasebold() | |
199 | */ | |
200 | 0 | @Override |
201 | public boolean isUpperCasebold() | |
202 | { | |
203 | 0 | return viewStyle.isUpperCasebold(); |
204 | } | |
205 | ||
206 | /** | |
207 | * @return | |
208 | * @see jalview.api.ViewStyleI#isSeqNameItalics() | |
209 | */ | |
210 | 3187 | @Override |
211 | public boolean isSeqNameItalics() | |
212 | { | |
213 | 3187 | return viewStyle.isSeqNameItalics(); |
214 | } | |
215 | ||
216 | /** | |
217 | * @param colourByReferenceSeq | |
218 | * @see jalview.api.ViewStyleI#setColourByReferenceSeq(boolean) | |
219 | */ | |
220 | 10 | @Override |
221 | public void setColourByReferenceSeq(boolean colourByReferenceSeq) | |
222 | { | |
223 | 10 | viewStyle.setColourByReferenceSeq(colourByReferenceSeq); |
224 | } | |
225 | ||
226 | /** | |
227 | * @param b | |
228 | * @see jalview.api.ViewStyleI#setColourAppliesToAllGroups(boolean) | |
229 | */ | |
230 | 693 | @Override |
231 | public void setColourAppliesToAllGroups(boolean b) | |
232 | { | |
233 | 693 | viewStyle.setColourAppliesToAllGroups(b); |
234 | } | |
235 | ||
236 | /** | |
237 | * @return | |
238 | * @see jalview.api.ViewStyleI#getColourAppliesToAllGroups() | |
239 | */ | |
240 | 962 | @Override |
241 | public boolean getColourAppliesToAllGroups() | |
242 | { | |
243 | 962 | return viewStyle.getColourAppliesToAllGroups(); |
244 | } | |
245 | ||
246 | /** | |
247 | * @return | |
248 | * @see jalview.api.ViewStyleI#getAbovePIDThreshold() | |
249 | */ | |
250 | 878 | @Override |
251 | public boolean getAbovePIDThreshold() | |
252 | { | |
253 | 878 | return viewStyle.getAbovePIDThreshold(); |
254 | } | |
255 | ||
256 | 878 | @Override |
257 | public boolean getByConsensusSecondaryStructureSelected() | |
258 | { | |
259 | 878 | return viewStyle.getByConsensusSecondaryStructureSelected(); |
260 | } | |
261 | ||
262 | 85 | public void setShowStructureProvider(boolean b) |
263 | { | |
264 | 85 | viewStyle.setShowStructureProvider(b); |
265 | } | |
266 | ||
267 | 6725 | public boolean isShowStructureProvider() |
268 | { | |
269 | 6725 | return viewStyle.isShowStructureProvider(); |
270 | } | |
271 | ||
272 | /** | |
273 | * @param inc | |
274 | * @see jalview.api.ViewStyleI#setIncrement(int) | |
275 | */ | |
276 | 85 | @Override |
277 | public void setIncrement(int inc) | |
278 | { | |
279 | 85 | viewStyle.setIncrement(inc); |
280 | } | |
281 | ||
282 | /** | |
283 | * @return | |
284 | * @see jalview.api.ViewStyleI#getIncrement() | |
285 | */ | |
286 | 0 | @Override |
287 | public int getIncrement() | |
288 | { | |
289 | 0 | return viewStyle.getIncrement(); |
290 | } | |
291 | ||
292 | /** | |
293 | * @param inc | |
294 | * @see jalview.api.ViewStyleI#setConsensusSecondaryStructureThreshold(int) | |
295 | */ | |
296 | 85 | @Override |
297 | public void setConsensusSecondaryStructureThreshold(int val) | |
298 | { | |
299 | 85 | viewStyle.setConsensusSecondaryStructureThreshold(val); |
300 | } | |
301 | ||
302 | /** | |
303 | * @return | |
304 | * @see jalview.api.ViewStyleI#getConsensusSecondaryStructureThreshold() | |
305 | */ | |
306 | 0 | @Override |
307 | public int getConsensusSecondaryStructureThreshold() | |
308 | { | |
309 | 0 | return viewStyle.getConsensusSecondaryStructureThreshold(); |
310 | } | |
311 | ||
312 | /** | |
313 | * @param b | |
314 | * @see jalview.api.ViewStyleI#setConservationSelected(boolean) | |
315 | */ | |
316 | 93 | @Override |
317 | public void setConservationSelected(boolean b) | |
318 | { | |
319 | 93 | viewStyle.setConservationSelected(b); |
320 | } | |
321 | ||
322 | /** | |
323 | * @param show | |
324 | * @see jalview.api.ViewStyleI#setShowHiddenMarkers(boolean) | |
325 | */ | |
326 | 0 | @Override |
327 | public void setShowHiddenMarkers(boolean show) | |
328 | { | |
329 | 0 | viewStyle.setShowHiddenMarkers(show); |
330 | } | |
331 | ||
332 | /** | |
333 | * @return | |
334 | * @see jalview.api.ViewStyleI#getShowHiddenMarkers() | |
335 | */ | |
336 | 7090 | @Override |
337 | public boolean getShowHiddenMarkers() | |
338 | { | |
339 | 7090 | return viewStyle.getShowHiddenMarkers(); |
340 | } | |
341 | ||
342 | /** | |
343 | * @param b | |
344 | * @see jalview.api.ViewStyleI#setScaleRightWrapped(boolean) | |
345 | */ | |
346 | 9 | @Override |
347 | public void setScaleRightWrapped(boolean b) | |
348 | { | |
349 | 9 | viewStyle.setScaleRightWrapped(b); |
350 | } | |
351 | ||
352 | /** | |
353 | * @param b | |
354 | * @see jalview.api.ViewStyleI#setScaleLeftWrapped(boolean) | |
355 | */ | |
356 | 11 | @Override |
357 | public void setScaleLeftWrapped(boolean b) | |
358 | { | |
359 | 11 | viewStyle.setScaleLeftWrapped(b); |
360 | } | |
361 | ||
362 | /** | |
363 | * @param b | |
364 | * @see jalview.api.ViewStyleI#setScaleAboveWrapped(boolean) | |
365 | */ | |
366 | 9 | @Override |
367 | public void setScaleAboveWrapped(boolean b) | |
368 | { | |
369 | 9 | viewStyle.setScaleAboveWrapped(b); |
370 | } | |
371 | ||
372 | /** | |
373 | * @return | |
374 | * @see jalview.api.ViewStyleI#getScaleLeftWrapped() | |
375 | */ | |
376 | 1308 | @Override |
377 | public boolean getScaleLeftWrapped() | |
378 | { | |
379 | 1308 | return viewStyle.getScaleLeftWrapped(); |
380 | } | |
381 | ||
382 | /** | |
383 | * @return | |
384 | * @see jalview.api.ViewStyleI#getScaleAboveWrapped() | |
385 | */ | |
386 | 913 | @Override |
387 | public boolean getScaleAboveWrapped() | |
388 | { | |
389 | 913 | return viewStyle.getScaleAboveWrapped(); |
390 | } | |
391 | ||
392 | /** | |
393 | * @return | |
394 | * @see jalview.api.ViewStyleI#getScaleRightWrapped() | |
395 | */ | |
396 | 2122 | @Override |
397 | public boolean getScaleRightWrapped() | |
398 | { | |
399 | 2122 | return viewStyle.getScaleRightWrapped(); |
400 | } | |
401 | ||
402 | /** | |
403 | * @param b | |
404 | * @see jalview.api.ViewStyleI#setAbovePIDThreshold(boolean) | |
405 | */ | |
406 | 94 | @Override |
407 | public void setAbovePIDThreshold(boolean b) | |
408 | { | |
409 | 94 | viewStyle.setAbovePIDThreshold(b); |
410 | } | |
411 | ||
412 | 85 | @Override |
413 | public void setByConsensusSecondaryStructureSelected(boolean b) | |
414 | { | |
415 | 85 | viewStyle.setByConsensusSecondaryStructureSelected(b); |
416 | } | |
417 | ||
418 | /** | |
419 | * @param thresh | |
420 | * @see jalview.api.ViewStyleI#setThreshold(int) | |
421 | */ | |
422 | 106 | @Override |
423 | public void setThreshold(int thresh) | |
424 | { | |
425 | 106 | viewStyle.setThreshold(thresh); |
426 | } | |
427 | ||
428 | /** | |
429 | * @return | |
430 | * @see jalview.api.ViewStyleI#getThreshold() | |
431 | */ | |
432 | 0 | @Override |
433 | public int getThreshold() | |
434 | { | |
435 | 0 | return viewStyle.getThreshold(); |
436 | } | |
437 | ||
438 | /** | |
439 | * @return | |
440 | * @see jalview.api.ViewStyleI#getShowJVSuffix() | |
441 | */ | |
442 | 48843 | @Override |
443 | public boolean getShowJVSuffix() | |
444 | { | |
445 | 48843 | return viewStyle.getShowJVSuffix(); |
446 | } | |
447 | ||
448 | /** | |
449 | * @param b | |
450 | * @see jalview.api.ViewStyleI#setShowJVSuffix(boolean) | |
451 | */ | |
452 | 86 | @Override |
453 | public void setShowJVSuffix(boolean b) | |
454 | { | |
455 | 86 | viewStyle.setShowJVSuffix(b); |
456 | } | |
457 | ||
458 | /** | |
459 | * @param state | |
460 | * @see jalview.api.ViewStyleI#setWrapAlignment(boolean) | |
461 | */ | |
462 | 97 | @Override |
463 | public void setWrapAlignment(boolean state) | |
464 | { | |
465 | 97 | viewStyle.setWrapAlignment(state); |
466 | 97 | ranges.setWrappedMode(state); |
467 | } | |
468 | ||
469 | /** | |
470 | * @param state | |
471 | * @see jalview.api.ViewStyleI#setShowText(boolean) | |
472 | */ | |
473 | 85 | @Override |
474 | public void setShowText(boolean state) | |
475 | { | |
476 | 85 | viewStyle.setShowText(state); |
477 | } | |
478 | ||
479 | /** | |
480 | * @param state | |
481 | * @see jalview.api.ViewStyleI#setRenderGaps(boolean) | |
482 | */ | |
483 | 85 | @Override |
484 | public void setRenderGaps(boolean state) | |
485 | { | |
486 | 85 | viewStyle.setRenderGaps(state); |
487 | } | |
488 | ||
489 | /** | |
490 | * @return | |
491 | * @see jalview.api.ViewStyleI#getColourText() | |
492 | */ | |
493 | 432784 | @Override |
494 | public boolean getColourText() | |
495 | { | |
496 | 432784 | return viewStyle.getColourText(); |
497 | } | |
498 | ||
499 | /** | |
500 | * @param state | |
501 | * @see jalview.api.ViewStyleI#setColourText(boolean) | |
502 | */ | |
503 | 85 | @Override |
504 | public void setColourText(boolean state) | |
505 | { | |
506 | 85 | viewStyle.setColourText(state); |
507 | } | |
508 | ||
509 | /** | |
510 | * @return | |
511 | * @see jalview.api.ViewStyleI#getWrapAlignment() | |
512 | */ | |
513 | 30632 | @Override |
514 | public boolean getWrapAlignment() | |
515 | { | |
516 | 30632 | return viewStyle.getWrapAlignment(); |
517 | } | |
518 | ||
519 | /** | |
520 | * @return | |
521 | * @see jalview.api.ViewStyleI#getShowText() | |
522 | */ | |
523 | 433456 | @Override |
524 | public boolean getShowText() | |
525 | { | |
526 | 433456 | return viewStyle.getShowText(); |
527 | } | |
528 | ||
529 | /** | |
530 | * @return | |
531 | * @see jalview.api.ViewStyleI#getWrappedWidth() | |
532 | */ | |
533 | 2 | @Override |
534 | public int getWrappedWidth() | |
535 | { | |
536 | 2 | return viewStyle.getWrappedWidth(); |
537 | } | |
538 | ||
539 | /** | |
540 | * @param w | |
541 | * @see jalview.api.ViewStyleI#setWrappedWidth(int) | |
542 | */ | |
543 | 842 | @Override |
544 | public void setWrappedWidth(int w) | |
545 | { | |
546 | 842 | viewStyle.setWrappedWidth(w); |
547 | } | |
548 | ||
549 | /** | |
550 | * @return | |
551 | * @see jalview.api.ViewStyleI#getCharHeight() | |
552 | */ | |
553 | 115242 | @Override |
554 | public int getCharHeight() | |
555 | { | |
556 | 115243 | return viewStyle.getCharHeight(); |
557 | } | |
558 | ||
559 | /** | |
560 | * @param h | |
561 | * @see jalview.api.ViewStyleI#setCharHeight(int) | |
562 | */ | |
563 | 596 | @Override |
564 | public void setCharHeight(int h) | |
565 | { | |
566 | 596 | viewStyle.setCharHeight(h); |
567 | } | |
568 | ||
569 | /** | |
570 | * @return | |
571 | * @see jalview.api.ViewStyleI#getCharWidth() | |
572 | */ | |
573 | 1521110 | @Override |
574 | public int getCharWidth() | |
575 | { | |
576 | 1521110 | return viewStyle.getCharWidth(); |
577 | } | |
578 | ||
579 | /** | |
580 | * @param w | |
581 | * @see jalview.api.ViewStyleI#setCharWidth(int) | |
582 | */ | |
583 | 599 | @Override |
584 | public void setCharWidth(int w) | |
585 | { | |
586 | 599 | viewStyle.setCharWidth(w); |
587 | } | |
588 | ||
589 | /** | |
590 | * @return | |
591 | * @see jalview.api.ViewStyleI#getShowBoxes() | |
592 | */ | |
593 | 471267 | @Override |
594 | public boolean getShowBoxes() | |
595 | { | |
596 | 471269 | return viewStyle.getShowBoxes(); |
597 | } | |
598 | ||
599 | /** | |
600 | * @return | |
601 | * @see jalview.api.ViewStyleI#getShowUnconserved() | |
602 | */ | |
603 | 430966 | @Override |
604 | public boolean getShowUnconserved() | |
605 | { | |
606 | 430966 | return viewStyle.getShowUnconserved(); |
607 | } | |
608 | ||
609 | /** | |
610 | * @param showunconserved | |
611 | * @see jalview.api.ViewStyleI#setShowUnconserved(boolean) | |
612 | */ | |
613 | 85 | @Override |
614 | public void setShowUnconserved(boolean showunconserved) | |
615 | { | |
616 | 85 | viewStyle.setShowUnconserved(showunconserved); |
617 | } | |
618 | ||
619 | /** | |
620 | * @param default1 | |
621 | * @see jalview.api.ViewStyleI#setSeqNameItalics(boolean) | |
622 | */ | |
623 | 0 | @Override |
624 | public void setSeqNameItalics(boolean default1) | |
625 | { | |
626 | 0 | viewStyle.setSeqNameItalics(default1); |
627 | } | |
628 | ||
629 | 208173 | @Override |
630 | public AlignmentI getAlignment() | |
631 | { | |
632 | 208173 | return alignment; |
633 | } | |
634 | ||
635 | 0 | @Override |
636 | public char getGapCharacter() | |
637 | { | |
638 | 0 | return alignment.getGapCharacter(); |
639 | } | |
640 | ||
641 | protected String sequenceSetID; | |
642 | ||
643 | /** | |
644 | * probably unused indicator that view is of a dataset rather than an | |
645 | * alignment | |
646 | */ | |
647 | protected boolean isDataset = false; | |
648 | ||
649 | 0 | public void setDataset(boolean b) |
650 | { | |
651 | 0 | isDataset = b; |
652 | } | |
653 | ||
654 | 478 | public boolean isDataset() |
655 | { | |
656 | 478 | return isDataset; |
657 | } | |
658 | ||
659 | private Map<SequenceI, SequenceCollectionI> hiddenRepSequences; | |
660 | ||
661 | protected ColumnSelection colSel = new ColumnSelection(); | |
662 | ||
663 | public boolean autoCalculateConsensus = true; | |
664 | ||
665 | protected boolean autoCalculateStrucConsensus = true; | |
666 | ||
667 | protected boolean ignoreGapsInConsensusCalculation = false; | |
668 | ||
669 | protected ResidueShaderI residueShading = new ResidueShader(); | |
670 | ||
671 | 274 | @Override |
672 | public void setGlobalColourScheme(ColourSchemeI cs) | |
673 | { | |
674 | // TODO: logic refactored from AlignFrame changeColour - | |
675 | // TODO: autorecalc stuff should be changed to rely on the worker system | |
676 | // check to see if we should implement a changeColour(cs) method rather than | |
677 | // put the logic in here | |
678 | // - means that caller decides if they want to just modify state and defer | |
679 | // calculation till later or to do all calculations in thread. | |
680 | // via changecolour | |
681 | ||
682 | /* | |
683 | * only instantiate alignment colouring once, thereafter update it; | |
684 | * this means that any conservation or PID threshold settings | |
685 | * persist when the alignment colour scheme is changed | |
686 | */ | |
687 | 274 | if (residueShading == null) |
688 | { | |
689 | 0 | residueShading = new ResidueShader(viewStyle); |
690 | } | |
691 | 274 | residueShading.setColourScheme(cs); |
692 | ||
693 | // TODO: do threshold and increment belong in ViewStyle or ResidueShader? | |
694 | // ...problem: groups need these, but do not currently have a ViewStyle | |
695 | ||
696 | 274 | if (cs != null) |
697 | { | |
698 | 81 | if (getConservationSelected()) |
699 | { | |
700 | 15 | residueShading.setConservation(hconservation); |
701 | } | |
702 | /* | |
703 | * reset conservation flag in case just set to false if | |
704 | * Conservation was null (calculation still in progress) | |
705 | */ | |
706 | 81 | residueShading.setConservationApplied(getConservationSelected()); |
707 | 81 | residueShading.alignmentChanged(alignment, hiddenRepSequences); |
708 | } | |
709 | ||
710 | /* | |
711 | * if 'apply colour to all groups' is selected... do so | |
712 | * (but don't transfer any colour threshold settings to groups) | |
713 | */ | |
714 | 274 | if (getColourAppliesToAllGroups()) |
715 | { | |
716 | 86 | for (SequenceGroup sg : getAlignment().getGroups()) |
717 | { | |
718 | /* | |
719 | * retain any colour thresholds per group while | |
720 | * changing choice of colour scheme (JAL-2386) | |
721 | */ | |
722 | 9 | sg.setColourScheme(cs == null ? null : cs.getInstance(this, sg)); |
723 | 9 | if (cs != null) |
724 | { | |
725 | 8 | sg.getGroupColourScheme().alignmentChanged(sg, |
726 | hiddenRepSequences); | |
727 | } | |
728 | } | |
729 | } | |
730 | } | |
731 | ||
732 | 1399 | @Override |
733 | public ColourSchemeI getGlobalColourScheme() | |
734 | { | |
735 | 1399 | return residueShading == null ? null : residueShading.getColourScheme(); |
736 | } | |
737 | ||
738 | 475538 | @Override |
739 | public ResidueShaderI getResidueShading() | |
740 | { | |
741 | 475537 | return residueShading; |
742 | } | |
743 | ||
744 | protected AlignmentAnnotation consensus; | |
745 | ||
746 | protected List<AlignmentAnnotation> secondaryStructureConsensus; | |
747 | ||
748 | protected AlignmentAnnotation complementConsensus; | |
749 | ||
750 | protected AlignmentAnnotation gapcounts; | |
751 | ||
752 | protected AlignmentAnnotation strucConsensus; | |
753 | ||
754 | protected AlignmentAnnotation conservation; | |
755 | ||
756 | protected AlignmentAnnotation quality; | |
757 | ||
758 | protected AlignmentAnnotation[] groupConsensus; | |
759 | ||
760 | protected AlignmentAnnotation[] groupSSConsensus; | |
761 | ||
762 | protected AlignmentAnnotation[] groupConservation; | |
763 | ||
764 | /** | |
765 | * results of alignment consensus analysis for visible portion of view | |
766 | */ | |
767 | protected ProfilesI hconsensus = null; | |
768 | ||
769 | protected Map<String, ProfilesI> hSSConsensusProfileMap = null; | |
770 | ||
771 | ||
772 | /** | |
773 | * results of cDNA complement consensus visible portion of view | |
774 | */ | |
775 | protected Hashtable<String, Object>[] hcomplementConsensus = null; | |
776 | ||
777 | /** | |
778 | * results of secondary structure base pair consensus for visible portion of | |
779 | * view | |
780 | */ | |
781 | protected Hashtable<String, Object>[] hStrucConsensus = null; | |
782 | ||
783 | protected Conservation hconservation = null; | |
784 | ||
785 | 1016 | @Override |
786 | public void setConservation(Conservation cons) | |
787 | { | |
788 | 1016 | hconservation = cons; |
789 | } | |
790 | ||
791 | 1469 | @Override |
792 | public List<String> getSecondaryStructureSources() | |
793 | { | |
794 | 1469 | return viewStyle.getSecondaryStructureSources(); |
795 | } | |
796 | ||
797 | 961 | @Override |
798 | public void setSecondaryStructureSources( | |
799 | List<String> secondaryStructureSources) | |
800 | { | |
801 | 961 | viewStyle.setSecondaryStructureSources(secondaryStructureSources); |
802 | } | |
803 | ||
804 | 508 | protected void setSecondaryStructureSources(AlignmentAnnotation[] aa) |
805 | { | |
806 | 508 | List<String> sources = null; |
807 | ||
808 | 508 | if (aa != null) |
809 | { | |
810 | 416 | sources = AlignmentUtils.extractSSSourceInAlignmentAnnotation(aa); |
811 | 416 | if (sources != null) |
812 | { | |
813 | 416 | sources.add(0, Constants.SS_ALL_PROVIDERS); |
814 | 416 | viewStyle.setSecondaryStructureSources(sources); |
815 | } | |
816 | } | |
817 | } | |
818 | ||
819 | /** | |
820 | * percentage gaps allowed in a column before all amino acid properties should | |
821 | * be considered unconserved | |
822 | */ | |
823 | int ConsPercGaps = 25; // JBPNote : This should be a scalable property! | |
824 | ||
825 | 1866 | @Override |
826 | public int getConsPercGaps() | |
827 | { | |
828 | 1866 | return ConsPercGaps; |
829 | } | |
830 | ||
831 | 955 | @Override |
832 | public void setSequenceConsensusHash(ProfilesI hconsensus) | |
833 | { | |
834 | 955 | this.hconsensus = hconsensus; |
835 | } | |
836 | ||
837 | 961 | @Override |
838 | public void setSequenceSSConsensusHash( | |
839 | Map<String, ProfilesI> hSSConsensusProfileMap) | |
840 | { | |
841 | 961 | this.hSSConsensusProfileMap = hSSConsensusProfileMap; |
842 | } | |
843 | ||
844 | 4 | @Override |
845 | public void setComplementConsensusHash( | |
846 | Hashtable<String, Object>[] hconsensus) | |
847 | { | |
848 | 4 | this.hcomplementConsensus = hconsensus; |
849 | } | |
850 | ||
851 | 3430 | @Override |
852 | public ProfilesI getSequenceConsensusHash() | |
853 | { | |
854 | 3430 | return hconsensus; |
855 | } | |
856 | ||
857 | 3436 | @Override |
858 | public Map<String, ProfilesI> getSequenceSSConsensusHash() | |
859 | { | |
860 | 3436 | return hSSConsensusProfileMap; |
861 | } | |
862 | ||
863 | 2378 | @Override |
864 | public Hashtable<String, Object>[] getComplementConsensusHash() | |
865 | { | |
866 | 2378 | return hcomplementConsensus; |
867 | } | |
868 | ||
869 | 2378 | @Override |
870 | public Hashtable<String, Object>[] getRnaStructureConsensusHash() | |
871 | { | |
872 | 2378 | return hStrucConsensus; |
873 | } | |
874 | ||
875 | 4 | @Override |
876 | public void setRnaStructureConsensusHash( | |
877 | Hashtable<String, Object>[] hStrucConsensus) | |
878 | { | |
879 | 4 | this.hStrucConsensus = hStrucConsensus; |
880 | ||
881 | } | |
882 | ||
883 | 1457 | @Override |
884 | public AlignmentAnnotation getAlignmentQualityAnnot() | |
885 | { | |
886 | 1457 | return quality; |
887 | } | |
888 | ||
889 | 2340 | @Override |
890 | public AlignmentAnnotation getAlignmentConservationAnnotation() | |
891 | { | |
892 | 2340 | return conservation; |
893 | } | |
894 | ||
895 | 5661 | @Override |
896 | public AlignmentAnnotation getAlignmentConsensusAnnotation() | |
897 | { | |
898 | 5661 | return consensus; |
899 | } | |
900 | ||
901 | 5323 | @Override |
902 | public List<AlignmentAnnotation> getAlignmentSecondaryStructureConsensusAnnotation() | |
903 | { | |
904 | 5323 | return secondaryStructureConsensus; |
905 | } | |
906 | ||
907 | 5841 | @Override |
908 | public AlignmentAnnotation getAlignmentGapAnnotation() | |
909 | { | |
910 | 5841 | return gapcounts; |
911 | } | |
912 | ||
913 | 2386 | @Override |
914 | public AlignmentAnnotation getComplementConsensusAnnotation() | |
915 | { | |
916 | 2386 | return complementConsensus; |
917 | } | |
918 | ||
919 | 2378 | @Override |
920 | public AlignmentAnnotation getAlignmentStrucConsensusAnnotation() | |
921 | { | |
922 | 2378 | return strucConsensus; |
923 | } | |
924 | ||
925 | protected AlignCalcManagerI calculator = new AlignCalcManager(); | |
926 | ||
927 | /** | |
928 | * trigger update of conservation annotation | |
929 | */ | |
930 | 1000 | public void updateConservation(final AlignmentViewPanel ap) |
931 | { | |
932 | // see note in mantis : issue number 8585 | |
933 | 1000 | if (alignment.isNucleotide() |
934 | || (conservation == null && quality == null) | |
935 | || !autoCalculateConsensus) | |
936 | { | |
937 | 216 | return; |
938 | } | |
939 | 784 | if (calculator.getRegisteredWorkersOfClass( |
940 | jalview.workers.ConservationThread.class) == null) | |
941 | { | |
942 | 448 | calculator.registerWorker( |
943 | new jalview.workers.ConservationThread(this, ap)); | |
944 | } | |
945 | } | |
946 | ||
947 | /** | |
948 | * trigger update of consensus annotation | |
949 | */ | |
950 | 1009 | public void updateConsensus(final AlignmentViewPanel ap) |
951 | { | |
952 | // see note in mantis : issue number 8585 | |
953 | 1009 | if (consensus == null || !autoCalculateConsensus) |
954 | { | |
955 | 0 | return; |
956 | } | |
957 | 1009 | if (calculator |
958 | .getRegisteredWorkersOfClass(ConsensusThread.class) == null) | |
959 | { | |
960 | 455 | calculator.registerWorker(new ConsensusThread(this, ap)); |
961 | } | |
962 | ||
963 | /* | |
964 | * A separate thread to compute cDNA consensus for a protein alignment | |
965 | * which has mapping to cDNA | |
966 | */ | |
967 | 1009 | final AlignmentI al = this.getAlignment(); |
968 | 1009 | if (!al.isNucleotide() && al.getCodonFrames() != null |
969 | && !al.getCodonFrames().isEmpty()) | |
970 | { | |
971 | /* | |
972 | * fudge - check first for protein-to-nucleotide mappings | |
973 | * (we don't want to do this for protein-to-protein) | |
974 | */ | |
975 | 4 | boolean doConsensus = false; |
976 | 4 | for (AlignedCodonFrame mapping : al.getCodonFrames()) |
977 | { | |
978 | // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame? | |
979 | 4 | MapList[] mapLists = mapping.getdnaToProt(); |
980 | // mapLists can be empty if project load has not finished resolving seqs | |
981 | 4 | if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) |
982 | { | |
983 | 4 | doConsensus = true; |
984 | 4 | break; |
985 | } | |
986 | } | |
987 | 4 | if (doConsensus) |
988 | { | |
989 | 4 | if (calculator.getRegisteredWorkersOfClass( |
990 | ComplementConsensusThread.class) == null) | |
991 | { | |
992 | 4 | calculator |
993 | .registerWorker(new ComplementConsensusThread(this, ap)); | |
994 | } | |
995 | } | |
996 | } | |
997 | } | |
998 | ||
999 | /** | |
1000 | * trigger update of Secondary Structure consensus annotation | |
1001 | */ | |
1002 | 1009 | public void updateSecondaryStructureConsensus(final AlignmentViewPanel ap) |
1003 | { | |
1004 | // see note in mantis : issue number 8585 | |
1005 | 1009 | if (secondaryStructureConsensus == null || !autoCalculateConsensus) |
1006 | { | |
1007 | 0 | return; |
1008 | } | |
1009 | 1009 | List<String> ssSources = viewStyle.getSecondaryStructureSources(); |
1010 | 1009 | if (secondaryStructureConsensus.size() != ssSources.size()) |
1011 | { | |
1012 | ||
1013 | 73 | for (String source : ssSources) |
1014 | { | |
1015 | 85 | boolean ssConsensusForSourcePresent = false; |
1016 | 85 | for (AlignmentAnnotation aa : secondaryStructureConsensus) |
1017 | { | |
1018 | 24 | if (aa.description.startsWith(source)) |
1019 | { | |
1020 | 12 | ssConsensusForSourcePresent = true; |
1021 | 12 | break; |
1022 | } | |
1023 | } | |
1024 | ||
1025 | 85 | if (!ssConsensusForSourcePresent) |
1026 | { | |
1027 | 73 | AlignmentAnnotation ssConsensus = new AlignmentAnnotation( |
1028 | MessageManager.getString("label.ssconsensus_label") + " " | |
1029 | + source, | |
1030 | source + " " | |
1031 | + MessageManager | |
1032 | .getString("label.ssconsensus_descr"), | |
1033 | new Annotation[1], 0f, 100f, | |
1034 | AlignmentAnnotation.BAR_GRAPH); | |
1035 | ||
1036 | 73 | ssConsensus.hasText = true; |
1037 | 73 | ssConsensus.autoCalculated = true; |
1038 | 73 | secondaryStructureConsensus.add(ssConsensus); |
1039 | 73 | if (showSSConsensus) |
1040 | { | |
1041 | 0 | ssConsensus.visible = true; |
1042 | 0 | alignment.addAnnotation(ssConsensus); |
1043 | ||
1044 | } | |
1045 | } | |
1046 | } | |
1047 | } | |
1048 | 1009 | if (calculator.getRegisteredWorkersOfClass( |
1049 | SecondaryStructureConsensusThread.class) == null) | |
1050 | { | |
1051 | 458 | calculator.registerWorker( |
1052 | new SecondaryStructureConsensusThread(this, ap)); | |
1053 | } | |
1054 | 1009 | ap.adjustAnnotationHeight(); |
1055 | ||
1056 | } | |
1057 | ||
1058 | // --------START Structure Conservation | |
1059 | 1006 | public void updateStrucConsensus(final AlignmentViewPanel ap) |
1060 | { | |
1061 | 1006 | if (autoCalculateStrucConsensus && strucConsensus == null |
1062 | && alignment.isNucleotide() && alignment.hasRNAStructure()) | |
1063 | { | |
1064 | // secondary structure has been added - so init the consensus line | |
1065 | 0 | initRNAStructure(); |
1066 | } | |
1067 | ||
1068 | // see note in mantis : issue number 8585 | |
1069 | 1006 | if (strucConsensus == null || !autoCalculateStrucConsensus) |
1070 | { | |
1071 | 1003 | return; |
1072 | } | |
1073 | 3 | if (calculator.getRegisteredWorkersOfClass( |
1074 | StrucConsensusThread.class) == null) | |
1075 | { | |
1076 | 3 | calculator.registerWorker(new StrucConsensusThread(this, ap)); |
1077 | } | |
1078 | } | |
1079 | ||
1080 | 2735 | public boolean isCalcInProgress() |
1081 | { | |
1082 | 2735 | return calculator.isWorking(); |
1083 | } | |
1084 | ||
1085 | 9353 | @Override |
1086 | public boolean isCalculationInProgress( | |
1087 | AlignmentAnnotation alignmentAnnotation) | |
1088 | { | |
1089 | 9353 | if (!alignmentAnnotation.autoCalculated) |
1090 | { | |
1091 | 0 | return false; |
1092 | } | |
1093 | 9353 | if (calculator.workingInvolvedWith(alignmentAnnotation)) |
1094 | { | |
1095 | // jalview.bin.Console.errPrintln("grey out | |
1096 | // ("+alignmentAnnotation.label+")"); | |
1097 | 386 | return true; |
1098 | } | |
1099 | 8967 | return false; |
1100 | } | |
1101 | ||
1102 | 761 | public void setAlignment(AlignmentI align) |
1103 | { | |
1104 | 761 | this.alignment = align; |
1105 | } | |
1106 | ||
1107 | /** | |
1108 | * Clean up references when this viewport is closed | |
1109 | */ | |
1110 | 253 | @Override |
1111 | public void dispose() | |
1112 | { | |
1113 | /* | |
1114 | * defensively null out references to large objects in case | |
1115 | * this object is not garbage collected (as if!) | |
1116 | */ | |
1117 | 253 | consensus = null; |
1118 | 253 | complementConsensus = null; |
1119 | 253 | strucConsensus = null; |
1120 | 253 | secondaryStructureConsensus = null; |
1121 | 253 | conservation = null; |
1122 | 253 | quality = null; |
1123 | 253 | groupConsensus = null; |
1124 | 253 | groupConservation = null; |
1125 | 253 | hconsensus = null; |
1126 | 253 | hconservation = null; |
1127 | 253 | hcomplementConsensus = null; |
1128 | 253 | gapcounts = null; |
1129 | 253 | calculator = null; |
1130 | 253 | residueShading = null; // may hold a reference to Consensus |
1131 | 253 | changeSupport = null; |
1132 | 253 | ranges = null; |
1133 | 253 | currentTree = null; |
1134 | 253 | selectionGroup = null; |
1135 | 253 | colSel = null; |
1136 | 253 | setAlignment(null); |
1137 | } | |
1138 | ||
1139 | 3974 | @Override |
1140 | public boolean isClosed() | |
1141 | { | |
1142 | // TODO: check that this isClosed is only true after panel is closed, not | |
1143 | // before it is fully constructed. | |
1144 | 3974 | return alignment == null; |
1145 | } | |
1146 | ||
1147 | 1477 | @Override |
1148 | public AlignCalcManagerI getCalcManager() | |
1149 | { | |
1150 | 1477 | return calculator; |
1151 | } | |
1152 | ||
1153 | /** | |
1154 | * should conservation rows be shown for groups | |
1155 | */ | |
1156 | protected boolean showGroupConservation = false; | |
1157 | ||
1158 | /** | |
1159 | * should consensus rows be shown for groups | |
1160 | */ | |
1161 | protected boolean showGroupConsensus = false; | |
1162 | ||
1163 | protected boolean showGroupSSConsensus = false; | |
1164 | ||
1165 | /** | |
1166 | * should consensus profile be rendered by default | |
1167 | */ | |
1168 | protected boolean showSequenceLogo = false; | |
1169 | ||
1170 | /** | |
1171 | * should consensus profile be rendered normalised to row height | |
1172 | */ | |
1173 | protected boolean normaliseSequenceLogo = false; | |
1174 | ||
1175 | /** | |
1176 | * should consensus histograms be rendered by default | |
1177 | */ | |
1178 | protected boolean showConsensusHistogram = true; | |
1179 | ||
1180 | /** | |
1181 | * @return the showConsensusProfile | |
1182 | */ | |
1183 | 5125 | @Override |
1184 | public boolean isShowSequenceLogo() | |
1185 | { | |
1186 | 5125 | return showSequenceLogo; |
1187 | } | |
1188 | ||
1189 | /** | |
1190 | * @param showSequenceLogo | |
1191 | * the new value | |
1192 | */ | |
1193 | 85 | public void setShowSequenceLogo(boolean showSequenceLogo) |
1194 | { | |
1195 | 85 | if (showSequenceLogo != this.showSequenceLogo) |
1196 | { | |
1197 | // TODO: decouple settings setting from calculation when refactoring | |
1198 | // annotation update method from alignframe to viewport | |
1199 | 16 | this.showSequenceLogo = showSequenceLogo; |
1200 | 16 | calculator.updateAnnotationFor(ConsensusThread.class); |
1201 | 16 | calculator.updateAnnotationFor(ComplementConsensusThread.class); |
1202 | 16 | calculator.updateAnnotationFor(StrucConsensusThread.class); |
1203 | ||
1204 | // to do | |
1205 | ||
1206 | 16 | calculator |
1207 | .updateAnnotationFor(SecondaryStructureConsensusThread.class); | |
1208 | } | |
1209 | 85 | this.showSequenceLogo = showSequenceLogo; |
1210 | } | |
1211 | ||
1212 | /** | |
1213 | * @param showConsensusHistogram | |
1214 | * the showConsensusHistogram to set | |
1215 | */ | |
1216 | 85 | public void setShowConsensusHistogram(boolean showConsensusHistogram) |
1217 | { | |
1218 | 85 | this.showConsensusHistogram = showConsensusHistogram; |
1219 | } | |
1220 | ||
1221 | /** | |
1222 | * @return the showGroupConservation | |
1223 | */ | |
1224 | 848 | public boolean isShowGroupConservation() |
1225 | { | |
1226 | 848 | return showGroupConservation; |
1227 | } | |
1228 | ||
1229 | /** | |
1230 | * @param showGroupConservation | |
1231 | * the showGroupConservation to set | |
1232 | */ | |
1233 | 85 | public void setShowGroupConservation(boolean showGroupConservation) |
1234 | { | |
1235 | 85 | this.showGroupConservation = showGroupConservation; |
1236 | } | |
1237 | ||
1238 | /** | |
1239 | * @return the showGroupConsensus | |
1240 | */ | |
1241 | 848 | public boolean isShowGroupConsensus() |
1242 | { | |
1243 | 848 | return showGroupConsensus; |
1244 | } | |
1245 | ||
1246 | 848 | public boolean isShowGroupSSConsensus() |
1247 | { | |
1248 | 848 | return showGroupSSConsensus; |
1249 | } | |
1250 | ||
1251 | /** | |
1252 | * @param showGroupConsensus | |
1253 | * the showGroupConsensus to set | |
1254 | */ | |
1255 | 85 | public void setShowGroupConsensus(boolean showGroupConsensus) |
1256 | { | |
1257 | 85 | this.showGroupConsensus = showGroupConsensus; |
1258 | } | |
1259 | ||
1260 | 85 | public void setShowGroupSSConsensus(boolean showGroupSSConsensus) |
1261 | { | |
1262 | 85 | this.showGroupSSConsensus = showGroupSSConsensus; |
1263 | } | |
1264 | ||
1265 | /** | |
1266 | * @param showSSConsensus | |
1267 | * the showSSConsensus to set | |
1268 | */ | |
1269 | 0 | public void setShowSSConsensus(boolean showSSConsensus) |
1270 | { | |
1271 | 0 | this.showSSConsensus = showSSConsensus; |
1272 | } | |
1273 | ||
1274 | /** | |
1275 | * | |
1276 | * @return flag to indicate if the consensus histogram should be rendered by | |
1277 | * default | |
1278 | */ | |
1279 | 3222 | @Override |
1280 | public boolean isShowConsensusHistogram() | |
1281 | { | |
1282 | 3222 | return this.showConsensusHistogram; |
1283 | } | |
1284 | ||
1285 | /** | |
1286 | * when set, updateAlignment will always ensure sequences are of equal length | |
1287 | */ | |
1288 | private boolean padGaps = false; | |
1289 | ||
1290 | /** | |
1291 | * when set, alignment should be reordered according to a newly opened tree | |
1292 | */ | |
1293 | public boolean sortByTree = false; | |
1294 | ||
1295 | /** | |
1296 | * | |
1297 | * | |
1298 | * @return null or the currently selected sequence region | |
1299 | */ | |
1300 | 26658 | @Override |
1301 | public SequenceGroup getSelectionGroup() | |
1302 | { | |
1303 | 26658 | return selectionGroup; |
1304 | } | |
1305 | ||
1306 | /** | |
1307 | * Set the selection group for this window. Also sets the current alignment as | |
1308 | * the context for the group, if it does not already have one. | |
1309 | * | |
1310 | * @param sg | |
1311 | * - group holding references to sequences in this alignment view | |
1312 | * | |
1313 | */ | |
1314 | 140 | @Override |
1315 | public void setSelectionGroup(SequenceGroup sg) | |
1316 | { | |
1317 | 140 | selectionGroup = sg; |
1318 | 140 | if (sg != null && sg.getContext() == null) |
1319 | { | |
1320 | 36 | sg.setContext(alignment); |
1321 | } | |
1322 | } | |
1323 | ||
1324 | 1 | public void setHiddenColumns(HiddenColumns hidden) |
1325 | { | |
1326 | 1 | this.alignment.setHiddenColumns(hidden); |
1327 | } | |
1328 | ||
1329 | 4870 | @Override |
1330 | public ColumnSelection getColumnSelection() | |
1331 | { | |
1332 | 4870 | return colSel; |
1333 | } | |
1334 | ||
1335 | 13 | @Override |
1336 | public void setColumnSelection(ColumnSelection colSel) | |
1337 | { | |
1338 | 13 | this.colSel = colSel; |
1339 | 13 | if (colSel != null) |
1340 | { | |
1341 | 13 | updateHiddenColumns(); |
1342 | } | |
1343 | 13 | isColSelChanged(true); |
1344 | } | |
1345 | ||
1346 | /** | |
1347 | * | |
1348 | * @return | |
1349 | */ | |
1350 | 32 | @Override |
1351 | public Map<SequenceI, SequenceCollectionI> getHiddenRepSequences() | |
1352 | { | |
1353 | 32 | return hiddenRepSequences; |
1354 | } | |
1355 | ||
1356 | 0 | @Override |
1357 | public void setHiddenRepSequences( | |
1358 | Map<SequenceI, SequenceCollectionI> hiddenRepSequences) | |
1359 | { | |
1360 | 0 | this.hiddenRepSequences = hiddenRepSequences; |
1361 | } | |
1362 | ||
1363 | 0 | @Override |
1364 | public boolean hasSelectedColumns() | |
1365 | { | |
1366 | 0 | ColumnSelection columnSelection = getColumnSelection(); |
1367 | 0 | return columnSelection != null && columnSelection.hasSelectedColumns(); |
1368 | } | |
1369 | ||
1370 | 8768 | @Override |
1371 | public boolean hasHiddenColumns() | |
1372 | { | |
1373 | 8768 | return alignment.getHiddenColumns() != null |
1374 | && alignment.getHiddenColumns().hasHiddenColumns(); | |
1375 | } | |
1376 | ||
1377 | 14 | public void updateHiddenColumns() |
1378 | { | |
1379 | // this method doesn't really do anything now. But - it could, since a | |
1380 | // column Selection could be in the process of modification | |
1381 | // hasHiddenColumns = colSel.hasHiddenColumns(); | |
1382 | } | |
1383 | ||
1384 | 4844 | @Override |
1385 | public boolean hasHiddenRows() | |
1386 | { | |
1387 | 4844 | return alignment.getHiddenSequences().getSize() > 0; |
1388 | } | |
1389 | ||
1390 | protected SequenceGroup selectionGroup; | |
1391 | ||
1392 | 85 | public void setSequenceSetId(String newid) |
1393 | { | |
1394 | 85 | if (sequenceSetID != null) |
1395 | { | |
1396 | 85 | jalview.bin.Console.errPrintln( |
1397 | "Warning - overwriting a sequenceSetId for a viewport!"); | |
1398 | } | |
1399 | 85 | sequenceSetID = new String(newid); |
1400 | } | |
1401 | ||
1402 | 4537 | @Override |
1403 | public String getSequenceSetId() | |
1404 | { | |
1405 | 4537 | if (sequenceSetID == null) |
1406 | { | |
1407 | 364 | sequenceSetID = alignment.hashCode() + ""; |
1408 | } | |
1409 | ||
1410 | 4537 | return sequenceSetID; |
1411 | } | |
1412 | ||
1413 | /** | |
1414 | * unique viewId for synchronizing state (e.g. with stored Jalview Project) | |
1415 | * | |
1416 | */ | |
1417 | protected String viewId = null; | |
1418 | ||
1419 | 598 | @Override |
1420 | public String getViewId() | |
1421 | { | |
1422 | 598 | if (viewId == null) |
1423 | { | |
1424 | 300 | viewId = this.getSequenceSetId() + "." + this.hashCode() + ""; |
1425 | } | |
1426 | 598 | return viewId; |
1427 | } | |
1428 | ||
1429 | 88 | public void setIgnoreGapsConsensus(boolean b, AlignmentViewPanel ap) |
1430 | { | |
1431 | 88 | ignoreGapsInConsensusCalculation = b; |
1432 | 88 | if (ap != null) |
1433 | { | |
1434 | 3 | updateConsensus(ap); |
1435 | 3 | updateSecondaryStructureConsensus(ap); |
1436 | 3 | if (residueShading != null) |
1437 | { | |
1438 | 3 | residueShading.setThreshold(residueShading.getThreshold(), |
1439 | ignoreGapsInConsensusCalculation); | |
1440 | } | |
1441 | } | |
1442 | ||
1443 | } | |
1444 | ||
1445 | private long sgrouphash = -1, colselhash = -1; | |
1446 | ||
1447 | /** | |
1448 | * checks current SelectionGroup against record of last hash value, and | |
1449 | * updates record. | |
1450 | * | |
1451 | * @param b | |
1452 | * update the record of last hash value | |
1453 | * | |
1454 | * @return true if SelectionGroup changed since last call (when b is true) | |
1455 | */ | |
1456 | 161 | public boolean isSelectionGroupChanged(boolean b) |
1457 | { | |
1458 | 161 | int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1 |
1459 | : selectionGroup.hashCode(); | |
1460 | 161 | if (hc != -1 && hc != sgrouphash) |
1461 | { | |
1462 | 9 | if (b) |
1463 | { | |
1464 | 9 | sgrouphash = hc; |
1465 | } | |
1466 | 9 | return true; |
1467 | } | |
1468 | 152 | return false; |
1469 | } | |
1470 | ||
1471 | /** | |
1472 | * checks current colsel against record of last hash value, and optionally | |
1473 | * updates record. | |
1474 | * | |
1475 | * @param b | |
1476 | * update the record of last hash value | |
1477 | * @return true if colsel changed since last call (when b is true) | |
1478 | */ | |
1479 | 173 | public boolean isColSelChanged(boolean b) |
1480 | { | |
1481 | 173 | int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode(); |
1482 | 173 | if (hc != -1 && hc != colselhash) |
1483 | { | |
1484 | 17 | if (b) |
1485 | { | |
1486 | 17 | colselhash = hc; |
1487 | } | |
1488 | 17 | return true; |
1489 | } | |
1490 | 156 | return false; |
1491 | } | |
1492 | ||
1493 | 4346 | @Override |
1494 | public boolean isIgnoreGapsConsensus() | |
1495 | { | |
1496 | 4346 | return ignoreGapsInConsensusCalculation; |
1497 | } | |
1498 | ||
1499 | // property change stuff | |
1500 | // JBPNote Prolly only need this in the applet version. | |
1501 | private PropertyChangeSupport changeSupport = new PropertyChangeSupport( | |
1502 | this); | |
1503 | ||
1504 | protected boolean showConservation = true; | |
1505 | ||
1506 | protected boolean showQuality = true; | |
1507 | ||
1508 | protected boolean showConsensus = true; | |
1509 | ||
1510 | protected boolean showSSConsensus = true; | |
1511 | ||
1512 | protected boolean showOccupancy = true; | |
1513 | ||
1514 | private Map<SequenceI, Color> sequenceColours = new HashMap<>(); | |
1515 | ||
1516 | private Map<AlignmentAnnotation, Color> annotationColours = new HashMap<>(); | |
1517 | ||
1518 | protected SequenceAnnotationOrder sortAnnotationsBy = null; | |
1519 | ||
1520 | protected boolean showAutocalculatedAbove; | |
1521 | ||
1522 | /** | |
1523 | * when set, view will scroll to show the highlighted position | |
1524 | */ | |
1525 | private boolean followHighlight = true; | |
1526 | ||
1527 | /** | |
1528 | * Property change listener for changes in alignment | |
1529 | * | |
1530 | * @param listener | |
1531 | * DOCUMENT ME! | |
1532 | */ | |
1533 | 492 | public void addPropertyChangeListener( |
1534 | java.beans.PropertyChangeListener listener) | |
1535 | { | |
1536 | 492 | changeSupport.addPropertyChangeListener(listener); |
1537 | } | |
1538 | ||
1539 | /** | |
1540 | * DOCUMENT ME! | |
1541 | * | |
1542 | * @param listener | |
1543 | * DOCUMENT ME! | |
1544 | */ | |
1545 | 265 | public void removePropertyChangeListener( |
1546 | java.beans.PropertyChangeListener listener) | |
1547 | { | |
1548 | 265 | if (changeSupport != null) |
1549 | { | |
1550 | 264 | changeSupport.removePropertyChangeListener(listener); |
1551 | } | |
1552 | } | |
1553 | ||
1554 | /** | |
1555 | * Property change listener for changes in alignment | |
1556 | * | |
1557 | * @param prop | |
1558 | * DOCUMENT ME! | |
1559 | * @param oldvalue | |
1560 | * DOCUMENT ME! | |
1561 | * @param newvalue | |
1562 | * DOCUMENT ME! | |
1563 | */ | |
1564 | 78 | public void firePropertyChange(String prop, Object oldvalue, |
1565 | Object newvalue) | |
1566 | { | |
1567 | 78 | changeSupport.firePropertyChange(prop, oldvalue, newvalue); |
1568 | } | |
1569 | ||
1570 | 0 | @Override |
1571 | public void notifyAlignmentChanged() | |
1572 | { | |
1573 | 0 | firePropertyChange("alignment", null, alignment); |
1574 | } | |
1575 | ||
1576 | // common hide/show column stuff | |
1577 | ||
1578 | 6 | public void hideSelectedColumns() |
1579 | { | |
1580 | 6 | if (colSel.isEmpty()) |
1581 | { | |
1582 | 2 | return; |
1583 | } | |
1584 | ||
1585 | 4 | colSel.hideSelectedColumns(alignment); |
1586 | 4 | setSelectionGroup(null); |
1587 | 4 | isColSelChanged(true); |
1588 | } | |
1589 | ||
1590 | 71 | public void hideColumns(int start, int end) |
1591 | { | |
1592 | 71 | if (start == end) |
1593 | { | |
1594 | 2 | colSel.hideSelectedColumns(start, alignment.getHiddenColumns()); |
1595 | } | |
1596 | else | |
1597 | { | |
1598 | 69 | alignment.getHiddenColumns().hideColumns(start, end); |
1599 | } | |
1600 | 71 | isColSelChanged(true); |
1601 | } | |
1602 | ||
1603 | 1 | public void showColumn(int col) |
1604 | { | |
1605 | 1 | alignment.getHiddenColumns().revealHiddenColumns(col, colSel); |
1606 | 1 | isColSelChanged(true); |
1607 | } | |
1608 | ||
1609 | 5 | public void showAllHiddenColumns() |
1610 | { | |
1611 | 5 | alignment.getHiddenColumns().revealAllHiddenColumns(colSel); |
1612 | 5 | isColSelChanged(true); |
1613 | } | |
1614 | ||
1615 | // common hide/show seq stuff | |
1616 | 1 | public void showAllHiddenSeqs() |
1617 | { | |
1618 | 1 | int startSeq = ranges.getStartSeq(); |
1619 | 1 | int endSeq = ranges.getEndSeq(); |
1620 | ||
1621 | 1 | if (alignment.getHiddenSequences().getSize() > 0) |
1622 | { | |
1623 | 1 | if (selectionGroup == null) |
1624 | { | |
1625 | 0 | selectionGroup = new SequenceGroup(); |
1626 | 0 | selectionGroup.setEndRes(alignment.getWidth() - 1); |
1627 | } | |
1628 | 1 | List<SequenceI> tmp = alignment.getHiddenSequences() |
1629 | .showAll(hiddenRepSequences); | |
1630 | 1 | for (SequenceI seq : tmp) |
1631 | { | |
1632 | 2 | selectionGroup.addSequence(seq, false); |
1633 | 2 | setSequenceAnnotationsVisible(seq, true); |
1634 | } | |
1635 | ||
1636 | 1 | hiddenRepSequences = null; |
1637 | ||
1638 | 1 | ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); |
1639 | ||
1640 | 1 | firePropertyChange("alignment", null, alignment.getSequences()); |
1641 | // used to set hasHiddenRows/hiddenRepSequences here, after the property | |
1642 | // changed event | |
1643 | 1 | sendSelection(); |
1644 | } | |
1645 | } | |
1646 | ||
1647 | 2 | public void showSequence(int index) |
1648 | { | |
1649 | 2 | int startSeq = ranges.getStartSeq(); |
1650 | 2 | int endSeq = ranges.getEndSeq(); |
1651 | ||
1652 | 2 | List<SequenceI> tmp = alignment.getHiddenSequences().showSequence(index, |
1653 | hiddenRepSequences); | |
1654 | 2 | if (tmp.size() > 0) |
1655 | { | |
1656 | 2 | if (selectionGroup == null) |
1657 | { | |
1658 | 2 | selectionGroup = new SequenceGroup(); |
1659 | 2 | selectionGroup.setEndRes(alignment.getWidth() - 1); |
1660 | } | |
1661 | ||
1662 | 2 | for (SequenceI seq : tmp) |
1663 | { | |
1664 | 3 | selectionGroup.addSequence(seq, false); |
1665 | 3 | setSequenceAnnotationsVisible(seq, true); |
1666 | } | |
1667 | ||
1668 | 2 | ranges.setStartEndSeq(startSeq, endSeq + tmp.size()); |
1669 | ||
1670 | 2 | firePropertyChange("alignment", null, alignment.getSequences()); |
1671 | 2 | sendSelection(); |
1672 | } | |
1673 | } | |
1674 | ||
1675 | 0 | public void hideAllSelectedSeqs() |
1676 | { | |
1677 | 0 | if (selectionGroup == null || selectionGroup.getSize() < 1) |
1678 | { | |
1679 | 0 | return; |
1680 | } | |
1681 | ||
1682 | 0 | SequenceI[] seqs = selectionGroup.getSequencesInOrder(alignment); |
1683 | ||
1684 | 0 | hideSequence(seqs); |
1685 | ||
1686 | 0 | setSelectionGroup(null); |
1687 | } | |
1688 | ||
1689 | 54 | public void hideSequence(SequenceI[] seq) |
1690 | { | |
1691 | /* | |
1692 | * cache offset to first visible sequence | |
1693 | */ | |
1694 | 54 | int startSeq = ranges.getStartSeq(); |
1695 | ||
1696 | 54 | if (seq != null) |
1697 | { | |
1698 | 252 | for (int i = 0; i < seq.length; i++) |
1699 | { | |
1700 | 198 | alignment.getHiddenSequences().hideSequence(seq[i]); |
1701 | 198 | setSequenceAnnotationsVisible(seq[i], false); |
1702 | } | |
1703 | 54 | ranges.setStartSeq(startSeq); |
1704 | 54 | firePropertyChange("alignment", null, alignment.getSequences()); |
1705 | } | |
1706 | } | |
1707 | ||
1708 | /** | |
1709 | * Hides the specified sequence, or the sequences it represents | |
1710 | * | |
1711 | * @param sequence | |
1712 | * the sequence to hide, or keep as representative | |
1713 | * @param representGroup | |
1714 | * if true, hide the current selection group except for the | |
1715 | * representative sequence | |
1716 | */ | |
1717 | 3 | public void hideSequences(SequenceI sequence, boolean representGroup) |
1718 | { | |
1719 | 3 | if (selectionGroup == null || selectionGroup.getSize() < 1) |
1720 | { | |
1721 | 0 | hideSequence(new SequenceI[] { sequence }); |
1722 | 0 | return; |
1723 | } | |
1724 | ||
1725 | 3 | if (representGroup) |
1726 | { | |
1727 | 3 | hideRepSequences(sequence, selectionGroup); |
1728 | 3 | setSelectionGroup(null); |
1729 | 3 | return; |
1730 | } | |
1731 | ||
1732 | 0 | int gsize = selectionGroup.getSize(); |
1733 | 0 | SequenceI[] hseqs = selectionGroup.getSequences() |
1734 | .toArray(new SequenceI[gsize]); | |
1735 | ||
1736 | 0 | hideSequence(hseqs); |
1737 | 0 | setSelectionGroup(null); |
1738 | 0 | sendSelection(); |
1739 | } | |
1740 | ||
1741 | /** | |
1742 | * Set visibility for any annotations for the given sequence. | |
1743 | * | |
1744 | * @param sequenceI | |
1745 | */ | |
1746 | 203 | protected void setSequenceAnnotationsVisible(SequenceI sequenceI, |
1747 | boolean visible) | |
1748 | { | |
1749 | 203 | AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); |
1750 | 203 | if (anns != null) |
1751 | { | |
1752 | 203 | for (AlignmentAnnotation ann : anns) |
1753 | { | |
1754 | 1033 | if (ann.sequenceRef == sequenceI) |
1755 | { | |
1756 | 0 | ann.visible = visible; |
1757 | } | |
1758 | } | |
1759 | } | |
1760 | } | |
1761 | ||
1762 | 5 | public void hideRepSequences(SequenceI repSequence, SequenceGroup sg) |
1763 | { | |
1764 | 5 | int sSize = sg.getSize(); |
1765 | 5 | if (sSize < 2) |
1766 | { | |
1767 | 0 | return; |
1768 | } | |
1769 | ||
1770 | 5 | if (hiddenRepSequences == null) |
1771 | { | |
1772 | 5 | hiddenRepSequences = new Hashtable<>(); |
1773 | } | |
1774 | ||
1775 | 5 | hiddenRepSequences.put(repSequence, sg); |
1776 | ||
1777 | // Hide all sequences except the repSequence | |
1778 | 5 | SequenceI[] seqs = new SequenceI[sSize - 1]; |
1779 | 5 | int index = 0; |
1780 | 16 | for (int i = 0; i < sSize; i++) |
1781 | { | |
1782 | 11 | if (sg.getSequenceAt(i) != repSequence) |
1783 | { | |
1784 | 6 | if (index == sSize - 1) |
1785 | { | |
1786 | 0 | return; |
1787 | } | |
1788 | ||
1789 | 6 | seqs[index++] = sg.getSequenceAt(i); |
1790 | } | |
1791 | } | |
1792 | 5 | sg.setSeqrep(repSequence); // note: not done in 2.7applet |
1793 | 5 | sg.setHidereps(true); // note: not done in 2.7applet |
1794 | 5 | hideSequence(seqs); |
1795 | ||
1796 | } | |
1797 | ||
1798 | /** | |
1799 | * | |
1800 | * @return null or the current reference sequence | |
1801 | */ | |
1802 | 0 | public SequenceI getReferenceSeq() |
1803 | { | |
1804 | 0 | return alignment.getSeqrep(); |
1805 | } | |
1806 | ||
1807 | /** | |
1808 | * @param seq | |
1809 | * @return true iff seq is the reference for the alignment | |
1810 | */ | |
1811 | 5271 | public boolean isReferenceSeq(SequenceI seq) |
1812 | { | |
1813 | 5271 | return alignment.getSeqrep() == seq; |
1814 | } | |
1815 | ||
1816 | /** | |
1817 | * | |
1818 | * @param seq | |
1819 | * @return true if there are sequences represented by this sequence that are | |
1820 | * currently hidden | |
1821 | */ | |
1822 | 5322 | public boolean isHiddenRepSequence(SequenceI seq) |
1823 | { | |
1824 | 5322 | return (hiddenRepSequences != null |
1825 | && hiddenRepSequences.containsKey(seq)); | |
1826 | } | |
1827 | ||
1828 | /** | |
1829 | * | |
1830 | * @param seq | |
1831 | * @return null or a sequence group containing the sequences that seq | |
1832 | * represents | |
1833 | */ | |
1834 | 2 | public SequenceGroup getRepresentedSequences(SequenceI seq) |
1835 | { | |
1836 | 2 | return (SequenceGroup) (hiddenRepSequences == null ? null |
1837 | : hiddenRepSequences.get(seq)); | |
1838 | } | |
1839 | ||
1840 | 0 | @Override |
1841 | public int adjustForHiddenSeqs(int alignmentIndex) | |
1842 | { | |
1843 | 0 | return alignment.getHiddenSequences() |
1844 | .adjustForHiddenSeqs(alignmentIndex); | |
1845 | } | |
1846 | ||
1847 | 0 | @Override |
1848 | public void invertColumnSelection() | |
1849 | { | |
1850 | 0 | colSel.invertColumnSelection(0, alignment.getWidth(), alignment); |
1851 | 0 | isColSelChanged(true); |
1852 | } | |
1853 | ||
1854 | 4 | @Override |
1855 | public SequenceI[] getSelectionAsNewSequence() | |
1856 | { | |
1857 | 4 | SequenceI[] sequences; |
1858 | // JBPNote: Need to test jalviewLite.getSelectedSequencesAsAlignmentFrom - | |
1859 | // this was the only caller in the applet for this method | |
1860 | // JBPNote: in applet, this method returned references to the alignment | |
1861 | // sequences, and it did not honour the presence/absence of annotation | |
1862 | // attached to the alignment (probably!) | |
1863 | 4 | if (selectionGroup == null || selectionGroup.getSize() == 0) |
1864 | { | |
1865 | 2 | sequences = alignment.getSequencesArray(); |
1866 | 2 | AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation(); |
1867 | 4 | for (int i = 0; i < sequences.length; i++) |
1868 | { | |
1869 | // construct new sequence with subset of visible annotation | |
1870 | 2 | sequences[i] = new Sequence(sequences[i], annots); |
1871 | } | |
1872 | } | |
1873 | else | |
1874 | { | |
1875 | 2 | sequences = selectionGroup.getSelectionAsNewSequences(alignment); |
1876 | } | |
1877 | ||
1878 | 4 | return sequences; |
1879 | } | |
1880 | ||
1881 | 28 | @Override |
1882 | public SequenceI[] getSequenceSelection() | |
1883 | { | |
1884 | 28 | SequenceI[] sequences = null; |
1885 | 28 | if (selectionGroup != null) |
1886 | { | |
1887 | 4 | sequences = selectionGroup.getSequencesInOrder(alignment); |
1888 | } | |
1889 | 28 | if (sequences == null) |
1890 | { | |
1891 | 24 | sequences = alignment.getSequencesArray(); |
1892 | } | |
1893 | 28 | return sequences; |
1894 | } | |
1895 | ||
1896 | 20 | @Override |
1897 | public jalview.datamodel.AlignmentView getAlignmentView( | |
1898 | boolean selectedOnly) | |
1899 | { | |
1900 | 20 | return getAlignmentView(selectedOnly, false); |
1901 | } | |
1902 | ||
1903 | 21 | @Override |
1904 | public jalview.datamodel.AlignmentView getAlignmentView( | |
1905 | boolean selectedOnly, boolean markGroups) | |
1906 | { | |
1907 | 21 | return new AlignmentView(alignment, alignment.getHiddenColumns(), |
1908 | selectionGroup, | |
1909 | alignment.getHiddenColumns() != null | |
1910 | && alignment.getHiddenColumns().hasHiddenColumns(), | |
1911 | selectedOnly, markGroups); | |
1912 | } | |
1913 | ||
1914 | 24 | @Override |
1915 | public String[] getViewAsString(boolean selectedRegionOnly) | |
1916 | { | |
1917 | 24 | return getViewAsString(selectedRegionOnly, true); |
1918 | } | |
1919 | ||
1920 | 24 | @Override |
1921 | public String[] getViewAsString(boolean selectedRegionOnly, | |
1922 | boolean exportHiddenSeqs) | |
1923 | { | |
1924 | 24 | String[] selection = null; |
1925 | 24 | SequenceI[] seqs = null; |
1926 | 24 | int i, iSize; |
1927 | 24 | int start = 0, end = 0; |
1928 | 24 | if (selectedRegionOnly && selectionGroup != null) |
1929 | { | |
1930 | 0 | iSize = selectionGroup.getSize(); |
1931 | 0 | seqs = selectionGroup.getSequencesInOrder(alignment); |
1932 | 0 | start = selectionGroup.getStartRes(); |
1933 | 0 | end = selectionGroup.getEndRes() + 1; |
1934 | } | |
1935 | else | |
1936 | { | |
1937 | 24 | if (hasHiddenRows() && exportHiddenSeqs) |
1938 | { | |
1939 | 0 | AlignmentI fullAlignment = alignment.getHiddenSequences() |
1940 | .getFullAlignment(); | |
1941 | 0 | iSize = fullAlignment.getHeight(); |
1942 | 0 | seqs = fullAlignment.getSequencesArray(); |
1943 | 0 | end = fullAlignment.getWidth(); |
1944 | } | |
1945 | else | |
1946 | { | |
1947 | 24 | iSize = alignment.getHeight(); |
1948 | 24 | seqs = alignment.getSequencesArray(); |
1949 | 24 | end = alignment.getWidth(); |
1950 | } | |
1951 | } | |
1952 | ||
1953 | 24 | selection = new String[iSize]; |
1954 | 24 | if (alignment.getHiddenColumns() != null |
1955 | && alignment.getHiddenColumns().hasHiddenColumns()) | |
1956 | { | |
1957 | 206 | for (i = 0; i < iSize; i++) |
1958 | { | |
1959 | 188 | Iterator<int[]> blocks = alignment.getHiddenColumns() |
1960 | .getVisContigsIterator(start, end + 1, false); | |
1961 | 188 | selection[i] = seqs[i].getSequenceStringFromIterator(blocks); |
1962 | } | |
1963 | } | |
1964 | else | |
1965 | { | |
1966 | 36 | for (i = 0; i < iSize; i++) |
1967 | { | |
1968 | 30 | selection[i] = seqs[i].getSequenceAsString(start, end); |
1969 | } | |
1970 | ||
1971 | } | |
1972 | 24 | return selection; |
1973 | } | |
1974 | ||
1975 | 0 | @Override |
1976 | public List<int[]> getVisibleRegionBoundaries(int min, int max) | |
1977 | { | |
1978 | 0 | ArrayList<int[]> regions = new ArrayList<>(); |
1979 | 0 | int start = min; |
1980 | 0 | int end = max; |
1981 | ||
1982 | 0 | do |
1983 | { | |
1984 | 0 | HiddenColumns hidden = alignment.getHiddenColumns(); |
1985 | 0 | if (hidden != null && hidden.hasHiddenColumns()) |
1986 | { | |
1987 | 0 | if (start == 0) |
1988 | { | |
1989 | 0 | start = hidden.visibleToAbsoluteColumn(start); |
1990 | } | |
1991 | ||
1992 | 0 | end = hidden.getNextHiddenBoundary(false, start); |
1993 | 0 | if (start == end) |
1994 | { | |
1995 | 0 | end = max; |
1996 | } | |
1997 | 0 | if (end > max) |
1998 | { | |
1999 | 0 | end = max; |
2000 | } | |
2001 | } | |
2002 | ||
2003 | 0 | regions.add(new int[] { start, end }); |
2004 | ||
2005 | 0 | if (hidden != null && hidden.hasHiddenColumns()) |
2006 | { | |
2007 | 0 | start = hidden.visibleToAbsoluteColumn(end); |
2008 | 0 | start = hidden.getNextHiddenBoundary(true, start) + 1; |
2009 | } | |
2010 | 0 | } while (end < max); |
2011 | ||
2012 | // int[][] startEnd = new int[regions.size()][2]; | |
2013 | ||
2014 | 0 | return regions; |
2015 | } | |
2016 | ||
2017 | 1 | @Override |
2018 | public List<AlignmentAnnotation> getVisibleAlignmentAnnotation( | |
2019 | boolean selectedOnly) | |
2020 | { | |
2021 | 1 | ArrayList<AlignmentAnnotation> ala = new ArrayList<>(); |
2022 | 1 | AlignmentAnnotation[] aa; |
2023 | ? | if ((aa = alignment.getAlignmentAnnotation()) != null) |
2024 | { | |
2025 | 1 | for (AlignmentAnnotation annot : aa) |
2026 | { | |
2027 | 4 | AlignmentAnnotation clone = new AlignmentAnnotation(annot); |
2028 | 4 | if (selectedOnly && selectionGroup != null) |
2029 | { | |
2030 | 4 | clone.makeVisibleAnnotation(selectionGroup.getStartRes(), |
2031 | selectionGroup.getEndRes(), alignment.getHiddenColumns()); | |
2032 | } | |
2033 | else | |
2034 | { | |
2035 | 0 | clone.makeVisibleAnnotation(alignment.getHiddenColumns()); |
2036 | } | |
2037 | 4 | ala.add(clone); |
2038 | } | |
2039 | } | |
2040 | 1 | return ala; |
2041 | } | |
2042 | ||
2043 | 1678 | @Override |
2044 | public boolean isPadGaps() | |
2045 | { | |
2046 | 1678 | return padGaps; |
2047 | } | |
2048 | ||
2049 | 508 | @Override |
2050 | public void setPadGaps(boolean padGaps) | |
2051 | { | |
2052 | 508 | this.padGaps = padGaps; |
2053 | } | |
2054 | ||
2055 | /** | |
2056 | * apply any post-edit constraints and trigger any calculations needed after | |
2057 | * an edit has been performed on the alignment | |
2058 | * | |
2059 | * @param ap | |
2060 | */ | |
2061 | 549 | @Override |
2062 | public void alignmentChanged(AlignmentViewPanel ap) | |
2063 | { | |
2064 | 549 | if (isPadGaps()) |
2065 | { | |
2066 | 310 | alignment.padGaps(); |
2067 | } | |
2068 | 549 | if (autoCalculateConsensus) |
2069 | { | |
2070 | 549 | updateConsensus(ap); |
2071 | 549 | updateSecondaryStructureConsensus(ap); |
2072 | } | |
2073 | 549 | if (hconsensus != null && autoCalculateConsensus) |
2074 | { | |
2075 | 543 | updateConservation(ap); |
2076 | } | |
2077 | 549 | if (autoCalculateStrucConsensus) |
2078 | { | |
2079 | 549 | updateStrucConsensus(ap); |
2080 | } | |
2081 | ||
2082 | // Reset endRes of groups if beyond alignment width | |
2083 | 549 | int alWidth = alignment.getWidth(); |
2084 | 549 | List<SequenceGroup> groups = alignment.getGroups(); |
2085 | 549 | if (groups != null) |
2086 | { | |
2087 | 549 | for (SequenceGroup sg : groups) |
2088 | { | |
2089 | 175 | if (sg.getEndRes() > alWidth) |
2090 | { | |
2091 | 0 | sg.setEndRes(alWidth - 1); |
2092 | } | |
2093 | } | |
2094 | } | |
2095 | ||
2096 | 549 | if (selectionGroup != null && selectionGroup.getEndRes() > alWidth) |
2097 | { | |
2098 | 0 | selectionGroup.setEndRes(alWidth - 1); |
2099 | } | |
2100 | ||
2101 | 549 | updateAllColourSchemes(); |
2102 | 549 | calculator.restartWorkers(); |
2103 | // alignment.adjustSequenceAnnotations(); | |
2104 | } | |
2105 | ||
2106 | /** | |
2107 | * reset scope and do calculations for all applied colourschemes on alignment | |
2108 | */ | |
2109 | 549 | void updateAllColourSchemes() |
2110 | { | |
2111 | 549 | ResidueShaderI rs = residueShading; |
2112 | 549 | if (rs != null) |
2113 | { | |
2114 | 549 | rs.alignmentChanged(alignment, hiddenRepSequences); |
2115 | ||
2116 | 549 | rs.setConsensus(hconsensus); |
2117 | 549 | if (rs.conservationApplied()) |
2118 | { | |
2119 | 3 | rs.setConservation(Conservation.calculateConservation("All", |
2120 | alignment.getSequences(), 0, alignment.getWidth(), false, | |
2121 | getConsPercGaps(), false)); | |
2122 | } | |
2123 | } | |
2124 | ||
2125 | 549 | for (SequenceGroup sg : alignment.getGroups()) |
2126 | { | |
2127 | 175 | if (sg.cs != null) |
2128 | { | |
2129 | 175 | sg.cs.alignmentChanged(sg, hiddenRepSequences); |
2130 | } | |
2131 | 175 | sg.recalcConservation(); |
2132 | } | |
2133 | } | |
2134 | ||
2135 | 508 | protected void initAutoAnnotation() |
2136 | { | |
2137 | // TODO: add menu option action that nulls or creates consensus object | |
2138 | // depending on if the user wants to see the annotation or not in a | |
2139 | // specific alignment | |
2140 | ||
2141 | 508 | if (hconsensus == null && !isDataset) |
2142 | { | |
2143 | 508 | if (!alignment.isNucleotide()) |
2144 | { | |
2145 | 397 | initConservation(); |
2146 | 397 | initQuality(); |
2147 | } | |
2148 | else | |
2149 | { | |
2150 | 111 | initRNAStructure(); |
2151 | } | |
2152 | 508 | consensus = new AlignmentAnnotation("Consensus", |
2153 | MessageManager.getString("label.consensus_descr"), | |
2154 | new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); | |
2155 | 508 | setSecondaryStructureSources(alignment.getAlignmentAnnotation()); |
2156 | 508 | List<String> secondaryStructureSources = getSecondaryStructureSources(); |
2157 | ||
2158 | 508 | if (secondaryStructureSources != null) |
2159 | { | |
2160 | ||
2161 | 508 | secondaryStructureConsensus = new ArrayList<AlignmentAnnotation>(); |
2162 | 508 | for (String ssSource : secondaryStructureSources) |
2163 | { | |
2164 | ||
2165 | 434 | AlignmentAnnotation ssConsensus = new AlignmentAnnotation( |
2166 | MessageManager.getString("label.ssconsensus_label") + " " | |
2167 | + ssSource, | |
2168 | ssSource + " " | |
2169 | + MessageManager | |
2170 | .getString("label.ssconsensus_descr"), | |
2171 | new Annotation[1], 0f, 100f, | |
2172 | AlignmentAnnotation.BAR_GRAPH); | |
2173 | 434 | secondaryStructureConsensus.add(ssConsensus); |
2174 | } | |
2175 | ||
2176 | } | |
2177 | ||
2178 | 508 | initConsensus(consensus); |
2179 | 508 | initSSConsensus(secondaryStructureConsensus); |
2180 | 508 | initGapCounts(); |
2181 | 508 | initComplementConsensus(); |
2182 | } | |
2183 | } | |
2184 | ||
2185 | /** | |
2186 | * If this is a protein alignment and there are mappings to cDNA, adds the | |
2187 | * cDNA consensus annotation and returns true, else returns false. | |
2188 | */ | |
2189 | 518 | public boolean initComplementConsensus() |
2190 | { | |
2191 | 518 | if (!alignment.isNucleotide()) |
2192 | { | |
2193 | 406 | final List<AlignedCodonFrame> codonMappings = alignment |
2194 | .getCodonFrames(); | |
2195 | 406 | if (codonMappings != null && !codonMappings.isEmpty()) |
2196 | { | |
2197 | 4 | boolean doConsensus = false; |
2198 | 4 | for (AlignedCodonFrame mapping : codonMappings) |
2199 | { | |
2200 | // TODO hold mapping type e.g. dna-to-protein in AlignedCodonFrame? | |
2201 | 4 | MapList[] mapLists = mapping.getdnaToProt(); |
2202 | // mapLists can be empty if project load has not finished resolving | |
2203 | // seqs | |
2204 | 4 | if (mapLists.length > 0 && mapLists[0].getFromRatio() == 3) |
2205 | { | |
2206 | 4 | doConsensus = true; |
2207 | 4 | break; |
2208 | } | |
2209 | } | |
2210 | 4 | if (doConsensus) |
2211 | { | |
2212 | 4 | complementConsensus = new AlignmentAnnotation("cDNA Consensus", |
2213 | MessageManager | |
2214 | .getString("label.complement_consensus_descr"), | |
2215 | new Annotation[1], 0f, 100f, | |
2216 | AlignmentAnnotation.BAR_GRAPH); | |
2217 | 4 | initConsensus(complementConsensus); |
2218 | 4 | return true; |
2219 | } | |
2220 | } | |
2221 | } | |
2222 | 514 | return false; |
2223 | } | |
2224 | ||
2225 | 512 | private void initConsensus(AlignmentAnnotation aa) |
2226 | { | |
2227 | 512 | aa.hasText = true; |
2228 | 512 | aa.autoCalculated = true; |
2229 | ||
2230 | 512 | if (showConsensus) |
2231 | { | |
2232 | 511 | alignment.addAnnotation(aa); |
2233 | } | |
2234 | } | |
2235 | ||
2236 | 508 | private void initSSConsensus( |
2237 | List<AlignmentAnnotation> secondaryStructureConsensuses) | |
2238 | { | |
2239 | 508 | if (secondaryStructureConsensuses == null) |
2240 | { | |
2241 | 0 | return; |
2242 | } | |
2243 | 508 | for (AlignmentAnnotation aa : secondaryStructureConsensuses) |
2244 | { | |
2245 | 434 | aa.hasText = true; |
2246 | 434 | aa.autoCalculated = true; |
2247 | ||
2248 | 434 | if (showSSConsensus) |
2249 | { | |
2250 | 0 | alignment.addAnnotation(aa); |
2251 | } | |
2252 | ||
2253 | } | |
2254 | } | |
2255 | ||
2256 | // these should be extracted from the view model - style and settings for | |
2257 | // derived annotation | |
2258 | 508 | private void initGapCounts() |
2259 | { | |
2260 | 508 | if (showOccupancy) |
2261 | { | |
2262 | 504 | gapcounts = new AlignmentAnnotation("Occupancy", |
2263 | MessageManager.getString("label.occupancy_descr"), | |
2264 | new Annotation[1], 0f, alignment.getHeight(), | |
2265 | AlignmentAnnotation.BAR_GRAPH); | |
2266 | 504 | gapcounts.hasText = true; |
2267 | 504 | gapcounts.autoCalculated = true; |
2268 | 504 | gapcounts.scaleColLabel = true; |
2269 | 504 | gapcounts.graph = AlignmentAnnotation.BAR_GRAPH; |
2270 | ||
2271 | 504 | alignment.addAnnotation(gapcounts); |
2272 | } | |
2273 | } | |
2274 | ||
2275 | 397 | private void initConservation() |
2276 | { | |
2277 | 397 | if (showConservation) |
2278 | { | |
2279 | 396 | if (conservation == null) |
2280 | { | |
2281 | 396 | conservation = new AlignmentAnnotation("Conservation", |
2282 | MessageManager.formatMessage("label.conservation_descr", | |
2283 | getConsPercGaps()), | |
2284 | new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); | |
2285 | 396 | conservation.hasText = true; |
2286 | 396 | conservation.autoCalculated = true; |
2287 | 396 | alignment.addAnnotation(conservation); |
2288 | } | |
2289 | } | |
2290 | } | |
2291 | ||
2292 | 397 | private void initQuality() |
2293 | { | |
2294 | 397 | if (showQuality) |
2295 | { | |
2296 | 397 | if (quality == null) |
2297 | { | |
2298 | 397 | quality = new AlignmentAnnotation("Quality", |
2299 | MessageManager.getString("label.quality_descr"), | |
2300 | new Annotation[1], 0f, 11f, AlignmentAnnotation.BAR_GRAPH); | |
2301 | 397 | quality.hasText = true; |
2302 | 397 | quality.autoCalculated = true; |
2303 | 397 | alignment.addAnnotation(quality); |
2304 | } | |
2305 | } | |
2306 | } | |
2307 | ||
2308 | 111 | private void initRNAStructure() |
2309 | { | |
2310 | 111 | if (alignment.hasRNAStructure() && strucConsensus == null) |
2311 | { | |
2312 | 2 | strucConsensus = new AlignmentAnnotation("StrucConsensus", |
2313 | MessageManager.getString("label.strucconsensus_descr"), | |
2314 | new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH); | |
2315 | 2 | strucConsensus.hasText = true; |
2316 | 2 | strucConsensus.autoCalculated = true; |
2317 | ||
2318 | 2 | if (showConsensus) |
2319 | { | |
2320 | 2 | alignment.addAnnotation(strucConsensus); |
2321 | } | |
2322 | } | |
2323 | } | |
2324 | ||
2325 | /* | |
2326 | * (non-Javadoc) | |
2327 | * | |
2328 | * @see jalview.api.AlignViewportI#calcPanelHeight() | |
2329 | */ | |
2330 | 4824 | @Override |
2331 | public int calcPanelHeight() | |
2332 | { | |
2333 | // setHeight of panels | |
2334 | 4824 | AlignmentAnnotation[] anns = getAlignment().getAlignmentAnnotation(); |
2335 | 4824 | int height = 0; |
2336 | 4824 | int charHeight = getCharHeight(); |
2337 | 4824 | if (anns != null) |
2338 | { | |
2339 | 4823 | BitSet graphgrp = new BitSet(); |
2340 | 4824 | for (AlignmentAnnotation aa : anns) |
2341 | { | |
2342 | 22509 | if (aa == null) |
2343 | { | |
2344 | 0 | jalview.bin.Console.errPrintln("Null annotation row: ignoring."); |
2345 | 0 | continue; |
2346 | } | |
2347 | 22508 | if (!aa.visible) |
2348 | { | |
2349 | 1776 | continue; |
2350 | } | |
2351 | 20732 | if (aa.graphGroup > -1) |
2352 | { | |
2353 | 390 | if (graphgrp.get(aa.graphGroup)) |
2354 | { | |
2355 | 195 | continue; |
2356 | } | |
2357 | else | |
2358 | { | |
2359 | 195 | graphgrp.set(aa.graphGroup); |
2360 | } | |
2361 | } | |
2362 | 20538 | aa.height = 0; |
2363 | ||
2364 | 20536 | if (aa.hasText) |
2365 | { | |
2366 | 18285 | aa.height += charHeight; |
2367 | } | |
2368 | ||
2369 | 20537 | if (aa.hasIcons) |
2370 | { | |
2371 | 894 | aa.height += 16; |
2372 | } | |
2373 | ||
2374 | 20537 | if (aa.graph > 0) |
2375 | { | |
2376 | 19150 | aa.height += aa.graphHeight + 20; |
2377 | } | |
2378 | ||
2379 | 20537 | if (aa.height == 0) |
2380 | { | |
2381 | 158 | aa.height = 20; |
2382 | } | |
2383 | ||
2384 | 20537 | height += aa.height; |
2385 | } | |
2386 | } | |
2387 | 4824 | if (height == 0) |
2388 | { | |
2389 | // set minimum | |
2390 | 23 | height = 20; |
2391 | } | |
2392 | 4824 | return height; |
2393 | } | |
2394 | ||
2395 | 130 | @Override |
2396 | public void updateGroupAnnotationSettings(boolean applyGlobalSettings, | |
2397 | boolean preserveNewGroupSettings) | |
2398 | { | |
2399 | 130 | boolean updateCalcs = false; |
2400 | 130 | boolean conv = isShowGroupConservation(); |
2401 | 130 | boolean cons = isShowGroupConsensus(); |
2402 | 130 | boolean sscons = isShowGroupSSConsensus(); |
2403 | 130 | boolean showprf = isShowSequenceLogo(); |
2404 | 130 | boolean showConsHist = isShowConsensusHistogram(); |
2405 | 130 | boolean normLogo = isNormaliseSequenceLogo(); |
2406 | ||
2407 | /** | |
2408 | * TODO reorder the annotation rows according to group/sequence ordering on | |
2409 | * alignment | |
2410 | */ | |
2411 | // boolean sortg = true; | |
2412 | ||
2413 | // remove old automatic annotation | |
2414 | // add any new annotation | |
2415 | ||
2416 | // intersect alignment annotation with alignment groups | |
2417 | ||
2418 | 130 | AlignmentAnnotation[] aan = alignment.getAlignmentAnnotation(); |
2419 | 130 | List<SequenceGroup> oldrfs = new ArrayList<>(); |
2420 | 130 | if (aan != null) |
2421 | { | |
2422 | 1021 | for (int an = 0; an < aan.length; an++) |
2423 | { | |
2424 | 891 | if (aan[an].autoCalculated && aan[an].groupRef != null) |
2425 | { | |
2426 | 0 | oldrfs.add(aan[an].groupRef); |
2427 | 0 | alignment.deleteAnnotation(aan[an], false); |
2428 | } | |
2429 | } | |
2430 | } | |
2431 | 130 | if (alignment.getGroups() != null) |
2432 | { | |
2433 | 130 | for (SequenceGroup sg : alignment.getGroups()) |
2434 | { | |
2435 | 56 | updateCalcs = false; |
2436 | 56 | if (applyGlobalSettings |
2437 | || (!preserveNewGroupSettings && !oldrfs.contains(sg))) | |
2438 | { | |
2439 | // set defaults for this group's conservation/consensus | |
2440 | 9 | sg.setshowSequenceLogo(showprf); |
2441 | 9 | sg.setShowConsensusHistogram(showConsHist); |
2442 | 9 | sg.setNormaliseSequenceLogo(normLogo); |
2443 | } | |
2444 | 56 | if (conv) |
2445 | { | |
2446 | 0 | updateCalcs = true; |
2447 | 0 | alignment.addAnnotation(sg.getConservationRow(), 0); |
2448 | } | |
2449 | 56 | if (cons) |
2450 | { | |
2451 | 24 | updateCalcs = true; |
2452 | 24 | alignment.addAnnotation(sg.getConsensus(), 0); |
2453 | } | |
2454 | 56 | if (sscons) |
2455 | { | |
2456 | 0 | updateCalcs = true; |
2457 | 0 | List<String> secondaryStructureSources = getSecondaryStructureSources(); |
2458 | 0 | if (secondaryStructureSources != null) |
2459 | { | |
2460 | 0 | List<AlignmentAnnotation> ssAa = sg |
2461 | .getSSConsensus(secondaryStructureSources); | |
2462 | 0 | if (ssAa != null) |
2463 | { | |
2464 | 0 | for (AlignmentAnnotation aa : ssAa) |
2465 | { | |
2466 | // Setting annotation visibility to true for the secondary | |
2467 | // structure consensus for all providers | |
2468 | 0 | if (aa.label.contains(Constants.SS_ALL_PROVIDERS)) |
2469 | { | |
2470 | 0 | aa.visible = true; |
2471 | } | |
2472 | 0 | alignment.addAnnotation(aa, 0); |
2473 | } | |
2474 | } | |
2475 | } | |
2476 | } | |
2477 | // refresh the annotation rows | |
2478 | 56 | if (updateCalcs) |
2479 | { | |
2480 | 24 | sg.recalcConservation(); |
2481 | } | |
2482 | } | |
2483 | } | |
2484 | 130 | oldrfs.clear(); |
2485 | } | |
2486 | ||
2487 | 26241 | @Override |
2488 | public boolean isDisplayReferenceSeq() | |
2489 | { | |
2490 | 26241 | return alignment.hasSeqrep() && viewStyle.isDisplayReferenceSeq(); |
2491 | } | |
2492 | ||
2493 | 10 | @Override |
2494 | public void setDisplayReferenceSeq(boolean displayReferenceSeq) | |
2495 | { | |
2496 | 10 | viewStyle.setDisplayReferenceSeq(displayReferenceSeq); |
2497 | } | |
2498 | ||
2499 | 5 | @Override |
2500 | public boolean isColourByReferenceSeq() | |
2501 | { | |
2502 | 5 | return alignment.hasSeqrep() && viewStyle.isColourByReferenceSeq(); |
2503 | } | |
2504 | ||
2505 | 19447 | @Override |
2506 | public Color getSequenceColour(SequenceI seq) | |
2507 | { | |
2508 | 19447 | Color sqc = sequenceColours.get(seq); |
2509 | 19447 | return (sqc == null ? Color.white : sqc); |
2510 | } | |
2511 | ||
2512 | 1192 | @Override |
2513 | public void setSequenceColour(SequenceI seq, Color col) | |
2514 | { | |
2515 | 1192 | if (col == null) |
2516 | { | |
2517 | 0 | sequenceColours.remove(seq); |
2518 | } | |
2519 | else | |
2520 | { | |
2521 | 1192 | sequenceColours.put(seq, col); |
2522 | } | |
2523 | } | |
2524 | ||
2525 | 5 | @Override |
2526 | public void updateSequenceIdColours() | |
2527 | { | |
2528 | 5 | for (SequenceGroup sg : alignment.getGroups()) |
2529 | { | |
2530 | 5 | if (sg.idColour != null) |
2531 | { | |
2532 | 0 | for (SequenceI s : sg.getSequences(getHiddenRepSequences())) |
2533 | { | |
2534 | 0 | sequenceColours.put(s, sg.idColour); |
2535 | } | |
2536 | } | |
2537 | } | |
2538 | } | |
2539 | ||
2540 | 0 | @Override |
2541 | public void clearSequenceColours() | |
2542 | { | |
2543 | 0 | sequenceColours.clear(); |
2544 | } | |
2545 | ||
2546 | ||
2547 | 3124 | @Override |
2548 | public Color getAnnotationColour(AlignmentAnnotation annot) | |
2549 | { | |
2550 | 3124 | Color annotColor = annotationColours.get(annot); |
2551 | 3124 | return (annotColor == null ? Color.white : annotColor); |
2552 | } | |
2553 | ||
2554 | 0 | @Override |
2555 | public void setAnnotationColour(AlignmentAnnotation annot, Color col) | |
2556 | { | |
2557 | 0 | if (col == null) |
2558 | { | |
2559 | 0 | annotationColours.remove(annot); |
2560 | } | |
2561 | else | |
2562 | { | |
2563 | 0 | annotationColours.put(annot, col); |
2564 | } | |
2565 | } | |
2566 | ||
2567 | 5 | @Override |
2568 | public void updateAnnotationColours() | |
2569 | { | |
2570 | 5 | for (SequenceGroup sg : alignment.getGroups()) |
2571 | { | |
2572 | 5 | if (sg.idColour != null) |
2573 | { | |
2574 | 0 | for (AlignmentAnnotation annot : sg.getAlignmentAnnotation()) |
2575 | { | |
2576 | 0 | annotationColours.put(annot, sg.idColour); |
2577 | } | |
2578 | } | |
2579 | } | |
2580 | } | |
2581 | ||
2582 | 0 | @Override |
2583 | public void clearAnnotationColours() | |
2584 | { | |
2585 | 0 | annotationColours.clear(); |
2586 | } | |
2587 | ||
2588 | 0 | @Override |
2589 | public Map<AlignmentAnnotation, Color> getAnnotationColours() | |
2590 | { | |
2591 | 0 | return annotationColours; |
2592 | } | |
2593 | ||
2594 | 0 | @Override |
2595 | public void setAnnotationColours( | |
2596 | Map<AlignmentAnnotation, Color> annotationColours) | |
2597 | { | |
2598 | 0 | this.annotationColours = annotationColours; |
2599 | } | |
2600 | ||
2601 | 1057 | @Override |
2602 | public AlignViewportI getCodingComplement() | |
2603 | { | |
2604 | 1057 | return this.codingComplement; |
2605 | } | |
2606 | ||
2607 | /** | |
2608 | * Set this as the (cDna/protein) complement of the given viewport. Also | |
2609 | * ensures the reverse relationship is set on the given viewport. | |
2610 | */ | |
2611 | 6 | @Override |
2612 | public void setCodingComplement(AlignViewportI av) | |
2613 | { | |
2614 | 6 | if (this == av) |
2615 | { | |
2616 | 0 | jalview.bin.Console |
2617 | .errPrintln("Ignoring recursive setCodingComplement request"); | |
2618 | } | |
2619 | else | |
2620 | { | |
2621 | 6 | this.codingComplement = av; |
2622 | // avoid infinite recursion! | |
2623 | 6 | if (av.getCodingComplement() != this) |
2624 | { | |
2625 | 3 | av.setCodingComplement(this); |
2626 | } | |
2627 | } | |
2628 | } | |
2629 | ||
2630 | 25 | @Override |
2631 | public boolean isNucleotide() | |
2632 | { | |
2633 | 25 | return getAlignment() == null ? false : getAlignment().isNucleotide(); |
2634 | } | |
2635 | ||
2636 | 1545874 | @Override |
2637 | public FeaturesDisplayedI getFeaturesDisplayed() | |
2638 | { | |
2639 | 1547488 | return featuresDisplayed; |
2640 | } | |
2641 | ||
2642 | 112 | @Override |
2643 | public void setFeaturesDisplayed(FeaturesDisplayedI featuresDisplayedI) | |
2644 | { | |
2645 | 112 | featuresDisplayed = featuresDisplayedI; |
2646 | } | |
2647 | ||
2648 | 83 | @Override |
2649 | public boolean areFeaturesDisplayed() | |
2650 | { | |
2651 | 83 | return featuresDisplayed != null |
2652 | && featuresDisplayed.getRegisteredFeaturesCount() > 0; | |
2653 | } | |
2654 | ||
2655 | /** | |
2656 | * set the flag | |
2657 | * | |
2658 | * @param b | |
2659 | * features are displayed if true | |
2660 | */ | |
2661 | 141 | @Override |
2662 | public void setShowSequenceFeatures(boolean b) | |
2663 | { | |
2664 | 141 | viewStyle.setShowSequenceFeatures(b); |
2665 | } | |
2666 | ||
2667 | 459303 | @Override |
2668 | public boolean isShowSequenceFeatures() | |
2669 | { | |
2670 | 459330 | return viewStyle.isShowSequenceFeatures(); |
2671 | } | |
2672 | ||
2673 | 0 | @Override |
2674 | public void setShowSequenceFeaturesHeight(boolean selected) | |
2675 | { | |
2676 | 0 | viewStyle.setShowSequenceFeaturesHeight(selected); |
2677 | } | |
2678 | ||
2679 | 0 | @Override |
2680 | public boolean isShowSequenceFeaturesHeight() | |
2681 | { | |
2682 | 0 | return viewStyle.isShowSequenceFeaturesHeight(); |
2683 | } | |
2684 | ||
2685 | 680 | @Override |
2686 | public void setShowAnnotation(boolean b) | |
2687 | { | |
2688 | 680 | viewStyle.setShowAnnotation(b); |
2689 | } | |
2690 | ||
2691 | 4914 | @Override |
2692 | public boolean isShowAnnotation() | |
2693 | { | |
2694 | 4914 | return viewStyle.isShowAnnotation(); |
2695 | } | |
2696 | ||
2697 | 19268 | @Override |
2698 | public boolean isRightAlignIds() | |
2699 | { | |
2700 | 19268 | return viewStyle.isRightAlignIds(); |
2701 | } | |
2702 | ||
2703 | 593 | @Override |
2704 | public void setRightAlignIds(boolean rightAlignIds) | |
2705 | { | |
2706 | 593 | viewStyle.setRightAlignIds(rightAlignIds); |
2707 | } | |
2708 | ||
2709 | 1040 | @Override |
2710 | public boolean getConservationSelected() | |
2711 | { | |
2712 | 1040 | return viewStyle.getConservationSelected(); |
2713 | } | |
2714 | ||
2715 | 85 | @Override |
2716 | public void setShowBoxes(boolean state) | |
2717 | { | |
2718 | 85 | viewStyle.setShowBoxes(state); |
2719 | } | |
2720 | ||
2721 | /** | |
2722 | * @return | |
2723 | * @see jalview.api.ViewStyleI#getTextColour() | |
2724 | */ | |
2725 | 736782 | @Override |
2726 | public Color getTextColour() | |
2727 | { | |
2728 | 736782 | return viewStyle.getTextColour(); |
2729 | } | |
2730 | ||
2731 | /** | |
2732 | * @return | |
2733 | * @see jalview.api.ViewStyleI#getTextColour2() | |
2734 | */ | |
2735 | 46 | @Override |
2736 | public Color getTextColour2() | |
2737 | { | |
2738 | 46 | return viewStyle.getTextColour2(); |
2739 | } | |
2740 | ||
2741 | /** | |
2742 | * @return | |
2743 | * @see jalview.api.ViewStyleI#getThresholdTextColour() | |
2744 | */ | |
2745 | 432784 | @Override |
2746 | public int getThresholdTextColour() | |
2747 | { | |
2748 | 432784 | return viewStyle.getThresholdTextColour(); |
2749 | } | |
2750 | ||
2751 | /** | |
2752 | * @return | |
2753 | * @see jalview.api.ViewStyleI#isConservationColourSelected() | |
2754 | */ | |
2755 | 0 | @Override |
2756 | public boolean isConservationColourSelected() | |
2757 | { | |
2758 | 0 | return viewStyle.isConservationColourSelected(); |
2759 | } | |
2760 | ||
2761 | /** | |
2762 | * @return | |
2763 | * @see jalview.api.ViewStyleI#isRenderGaps() | |
2764 | */ | |
2765 | 3433 | @Override |
2766 | public boolean isRenderGaps() | |
2767 | { | |
2768 | 3433 | return viewStyle.isRenderGaps(); |
2769 | } | |
2770 | ||
2771 | /** | |
2772 | * @return | |
2773 | * @see jalview.api.ViewStyleI#isShowColourText() | |
2774 | */ | |
2775 | 672 | @Override |
2776 | public boolean isShowColourText() | |
2777 | { | |
2778 | 672 | return viewStyle.isShowColourText(); |
2779 | } | |
2780 | ||
2781 | /** | |
2782 | * @param conservationColourSelected | |
2783 | * @see jalview.api.ViewStyleI#setConservationColourSelected(boolean) | |
2784 | */ | |
2785 | 0 | @Override |
2786 | public void setConservationColourSelected( | |
2787 | boolean conservationColourSelected) | |
2788 | { | |
2789 | 0 | viewStyle.setConservationColourSelected(conservationColourSelected); |
2790 | } | |
2791 | ||
2792 | /** | |
2793 | * @param showColourText | |
2794 | * @see jalview.api.ViewStyleI#setShowColourText(boolean) | |
2795 | */ | |
2796 | 0 | @Override |
2797 | public void setShowColourText(boolean showColourText) | |
2798 | { | |
2799 | 0 | viewStyle.setShowColourText(showColourText); |
2800 | } | |
2801 | ||
2802 | /** | |
2803 | * @param textColour | |
2804 | * @see jalview.api.ViewStyleI#setTextColour(java.awt.Color) | |
2805 | */ | |
2806 | 85 | @Override |
2807 | public void setTextColour(Color textColour) | |
2808 | { | |
2809 | 85 | viewStyle.setTextColour(textColour); |
2810 | } | |
2811 | ||
2812 | /** | |
2813 | * @param thresholdTextColour | |
2814 | * @see jalview.api.ViewStyleI#setThresholdTextColour(int) | |
2815 | */ | |
2816 | 85 | @Override |
2817 | public void setThresholdTextColour(int thresholdTextColour) | |
2818 | { | |
2819 | 85 | viewStyle.setThresholdTextColour(thresholdTextColour); |
2820 | } | |
2821 | ||
2822 | /** | |
2823 | * @param textColour2 | |
2824 | * @see jalview.api.ViewStyleI#setTextColour2(java.awt.Color) | |
2825 | */ | |
2826 | 85 | @Override |
2827 | public void setTextColour2(Color textColour2) | |
2828 | { | |
2829 | 85 | viewStyle.setTextColour2(textColour2); |
2830 | } | |
2831 | ||
2832 | 143 | @Override |
2833 | public ViewStyleI getViewStyle() | |
2834 | { | |
2835 | 143 | return new ViewStyle(viewStyle); |
2836 | } | |
2837 | ||
2838 | 86 | @Override |
2839 | public void setViewStyle(ViewStyleI settingsForView) | |
2840 | { | |
2841 | 86 | viewStyle = new ViewStyle(settingsForView); |
2842 | 86 | if (residueShading != null) |
2843 | { | |
2844 | 86 | residueShading.setConservationApplied( |
2845 | settingsForView.isConservationColourSelected()); | |
2846 | } | |
2847 | } | |
2848 | ||
2849 | 0 | @Override |
2850 | public boolean sameStyle(ViewStyleI them) | |
2851 | { | |
2852 | 0 | return viewStyle.sameStyle(them); |
2853 | } | |
2854 | ||
2855 | /** | |
2856 | * @return | |
2857 | * @see jalview.api.ViewStyleI#getIdWidth() | |
2858 | */ | |
2859 | 6301 | @Override |
2860 | public int getIdWidth() | |
2861 | { | |
2862 | 6301 | return viewStyle.getIdWidth(); |
2863 | } | |
2864 | ||
2865 | /** | |
2866 | * @param i | |
2867 | * @see jalview.api.ViewStyleI#setIdWidth(int) | |
2868 | */ | |
2869 | 970 | @Override |
2870 | public void setIdWidth(int i) | |
2871 | { | |
2872 | 970 | viewStyle.setIdWidth(i); |
2873 | } | |
2874 | ||
2875 | /** | |
2876 | * @return | |
2877 | * @see jalview.api.ViewStyleI#isCentreColumnLabels() | |
2878 | */ | |
2879 | 672 | @Override |
2880 | public boolean isCentreColumnLabels() | |
2881 | { | |
2882 | 672 | return viewStyle.isCentreColumnLabels(); |
2883 | } | |
2884 | ||
2885 | /** | |
2886 | * @param centreColumnLabels | |
2887 | * @see jalview.api.ViewStyleI#setCentreColumnLabels(boolean) | |
2888 | */ | |
2889 | 593 | @Override |
2890 | public void setCentreColumnLabels(boolean centreColumnLabels) | |
2891 | { | |
2892 | 593 | viewStyle.setCentreColumnLabels(centreColumnLabels); |
2893 | } | |
2894 | ||
2895 | /** | |
2896 | * @param showdbrefs | |
2897 | * @see jalview.api.ViewStyleI#setShowDBRefs(boolean) | |
2898 | */ | |
2899 | 593 | @Override |
2900 | public void setShowDBRefs(boolean showdbrefs) | |
2901 | { | |
2902 | 593 | viewStyle.setShowDBRefs(showdbrefs); |
2903 | } | |
2904 | ||
2905 | /** | |
2906 | * @return | |
2907 | * @see jalview.api.ViewStyleI#isShowDBRefs() | |
2908 | */ | |
2909 | 718 | @Override |
2910 | public boolean isShowDBRefs() | |
2911 | { | |
2912 | 718 | return viewStyle.isShowDBRefs(); |
2913 | } | |
2914 | ||
2915 | /** | |
2916 | * @return | |
2917 | * @see jalview.api.ViewStyleI#isShowNPFeats() | |
2918 | */ | |
2919 | 718 | @Override |
2920 | public boolean isShowNPFeats() | |
2921 | { | |
2922 | 718 | return viewStyle.isShowNPFeats(); |
2923 | } | |
2924 | ||
2925 | /** | |
2926 | * @param shownpfeats | |
2927 | * @see jalview.api.ViewStyleI#setShowNPFeats(boolean) | |
2928 | */ | |
2929 | 593 | @Override |
2930 | public void setShowNPFeats(boolean shownpfeats) | |
2931 | { | |
2932 | 593 | viewStyle.setShowNPFeats(shownpfeats); |
2933 | } | |
2934 | ||
2935 | public abstract StructureSelectionManager getStructureSelectionManager(); | |
2936 | ||
2937 | /** | |
2938 | * Add one command to the command history list. | |
2939 | * | |
2940 | * @param command | |
2941 | */ | |
2942 | 1 | public void addToHistoryList(CommandI command) |
2943 | { | |
2944 | 1 | if (this.historyList != null) |
2945 | { | |
2946 | 1 | this.historyList.push(command); |
2947 | 1 | broadcastCommand(command, false); |
2948 | 1 | setSavedUpToDate(false); |
2949 | 1 | Jalview2XML.setStateSavedUpToDate(false); |
2950 | } | |
2951 | } | |
2952 | ||
2953 | 1 | protected void broadcastCommand(CommandI command, boolean undo) |
2954 | { | |
2955 | 1 | getStructureSelectionManager().commandPerformed(command, undo, |
2956 | getVamsasSource()); | |
2957 | } | |
2958 | ||
2959 | /** | |
2960 | * Add one command to the command redo list. | |
2961 | * | |
2962 | * @param command | |
2963 | */ | |
2964 | 0 | public void addToRedoList(CommandI command) |
2965 | { | |
2966 | 0 | if (this.redoList != null) |
2967 | { | |
2968 | 0 | this.redoList.push(command); |
2969 | } | |
2970 | 0 | broadcastCommand(command, true); |
2971 | } | |
2972 | ||
2973 | /** | |
2974 | * Clear the command redo list. | |
2975 | */ | |
2976 | 1 | public void clearRedoList() |
2977 | { | |
2978 | 1 | if (this.redoList != null) |
2979 | { | |
2980 | 1 | this.redoList.clear(); |
2981 | } | |
2982 | } | |
2983 | ||
2984 | 53 | public void setHistoryList(Deque<CommandI> list) |
2985 | { | |
2986 | 53 | this.historyList = list; |
2987 | } | |
2988 | ||
2989 | 1276 | public Deque<CommandI> getHistoryList() |
2990 | { | |
2991 | 1276 | return this.historyList; |
2992 | } | |
2993 | ||
2994 | 53 | public void setRedoList(Deque<CommandI> list) |
2995 | { | |
2996 | 53 | this.redoList = list; |
2997 | } | |
2998 | ||
2999 | 1275 | public Deque<CommandI> getRedoList() |
3000 | { | |
3001 | 1275 | return this.redoList; |
3002 | } | |
3003 | ||
3004 | 1 | @Override |
3005 | public VamsasSource getVamsasSource() | |
3006 | { | |
3007 | 1 | return this; |
3008 | } | |
3009 | ||
3010 | 5565 | public SequenceAnnotationOrder getSortAnnotationsBy() |
3011 | { | |
3012 | 5565 | return sortAnnotationsBy; |
3013 | } | |
3014 | ||
3015 | 0 | public void setSortAnnotationsBy( |
3016 | SequenceAnnotationOrder sortAnnotationsBy) | |
3017 | { | |
3018 | 0 | this.sortAnnotationsBy = sortAnnotationsBy; |
3019 | } | |
3020 | ||
3021 | 5565 | public boolean isShowAutocalculatedAbove() |
3022 | { | |
3023 | 5565 | return showAutocalculatedAbove; |
3024 | } | |
3025 | ||
3026 | 452 | public void setShowAutocalculatedAbove(boolean showAutocalculatedAbove) |
3027 | { | |
3028 | 452 | this.showAutocalculatedAbove = showAutocalculatedAbove; |
3029 | } | |
3030 | ||
3031 | 3 | @Override |
3032 | public boolean isScaleProteinAsCdna() | |
3033 | { | |
3034 | 3 | return viewStyle.isScaleProteinAsCdna(); |
3035 | } | |
3036 | ||
3037 | 0 | @Override |
3038 | public void setScaleProteinAsCdna(boolean b) | |
3039 | { | |
3040 | 0 | viewStyle.setScaleProteinAsCdna(b); |
3041 | } | |
3042 | ||
3043 | 0 | @Override |
3044 | public boolean isProteinFontAsCdna() | |
3045 | { | |
3046 | 0 | return viewStyle.isProteinFontAsCdna(); |
3047 | } | |
3048 | ||
3049 | 0 | @Override |
3050 | public void setProteinFontAsCdna(boolean b) | |
3051 | { | |
3052 | 0 | viewStyle.setProteinFontAsCdna(b); |
3053 | } | |
3054 | ||
3055 | 85 | @Override |
3056 | public void setShowComplementFeatures(boolean b) | |
3057 | { | |
3058 | 85 | viewStyle.setShowComplementFeatures(b); |
3059 | } | |
3060 | ||
3061 | 460669 | @Override |
3062 | public boolean isShowComplementFeatures() | |
3063 | { | |
3064 | 460714 | return viewStyle.isShowComplementFeatures(); |
3065 | } | |
3066 | ||
3067 | 85 | @Override |
3068 | public void setShowComplementFeaturesOnTop(boolean b) | |
3069 | { | |
3070 | 85 | viewStyle.setShowComplementFeaturesOnTop(b); |
3071 | } | |
3072 | ||
3073 | 47 | @Override |
3074 | public boolean isShowComplementFeaturesOnTop() | |
3075 | { | |
3076 | 47 | return viewStyle.isShowComplementFeaturesOnTop(); |
3077 | } | |
3078 | ||
3079 | /** | |
3080 | * @return true if view should scroll to show the highlighted region of a | |
3081 | * sequence | |
3082 | * @return | |
3083 | */ | |
3084 | 51 | @Override |
3085 | public final boolean isFollowHighlight() | |
3086 | { | |
3087 | 51 | return followHighlight; |
3088 | } | |
3089 | ||
3090 | 85 | @Override |
3091 | public final void setFollowHighlight(boolean b) | |
3092 | { | |
3093 | 85 | this.followHighlight = b; |
3094 | } | |
3095 | ||
3096 | 39785 | @Override |
3097 | public ViewportRanges getRanges() | |
3098 | { | |
3099 | 39785 | return ranges; |
3100 | } | |
3101 | ||
3102 | /** | |
3103 | * Helper method to populate the SearchResults with the location in the | |
3104 | * complementary alignment to scroll to, in order to match this one. | |
3105 | * | |
3106 | * @param sr | |
3107 | * the SearchResults to add to | |
3108 | * @return the offset (below top of visible region) of the matched sequence | |
3109 | */ | |
3110 | 637 | protected int findComplementScrollTarget(SearchResultsI sr) |
3111 | { | |
3112 | 637 | final AlignViewportI complement = getCodingComplement(); |
3113 | 637 | if (complement == null || !complement.isFollowHighlight()) |
3114 | { | |
3115 | 633 | return 0; |
3116 | } | |
3117 | 4 | boolean iAmProtein = !getAlignment().isNucleotide(); |
3118 | 4 | AlignmentI proteinAlignment = iAmProtein ? getAlignment() |
3119 | : complement.getAlignment(); | |
3120 | 4 | if (proteinAlignment == null) |
3121 | { | |
3122 | 0 | return 0; |
3123 | } | |
3124 | 4 | final List<AlignedCodonFrame> mappings = proteinAlignment |
3125 | .getCodonFrames(); | |
3126 | ||
3127 | /* | |
3128 | * Heuristic: find the first mapped sequence (if any) with a non-gapped | |
3129 | * residue in the middle column of the visible region. Scroll the | |
3130 | * complementary alignment to line up the corresponding residue. | |
3131 | */ | |
3132 | 4 | int seqOffset = 0; |
3133 | 4 | SequenceI sequence = null; |
3134 | ||
3135 | /* | |
3136 | * locate 'middle' column (true middle if an odd number visible, left of | |
3137 | * middle if an even number visible) | |
3138 | */ | |
3139 | 4 | int middleColumn = ranges.getStartRes() |
3140 | + (ranges.getEndRes() - ranges.getStartRes()) / 2; | |
3141 | 4 | final HiddenSequences hiddenSequences = getAlignment() |
3142 | .getHiddenSequences(); | |
3143 | ||
3144 | /* | |
3145 | * searching to the bottom of the alignment gives smoother scrolling across | |
3146 | * all gapped visible regions | |
3147 | */ | |
3148 | 4 | int lastSeq = alignment.getHeight() - 1; |
3149 | 4 | List<AlignedCodonFrame> seqMappings = null; |
3150 | 4 | for (int seqNo = ranges |
3151 | 4 | .getStartSeq(); seqNo <= lastSeq; seqNo++, seqOffset++) |
3152 | { | |
3153 | 4 | sequence = getAlignment().getSequenceAt(seqNo); |
3154 | 4 | if (hiddenSequences != null && hiddenSequences.isHidden(sequence)) |
3155 | { | |
3156 | 0 | continue; |
3157 | } | |
3158 | 4 | if (Comparison.isGap(sequence.getCharAt(middleColumn))) |
3159 | { | |
3160 | 0 | continue; |
3161 | } | |
3162 | 4 | seqMappings = MappingUtils.findMappingsForSequenceAndOthers(sequence, |
3163 | mappings, | |
3164 | getCodingComplement().getAlignment().getSequences()); | |
3165 | 4 | if (!seqMappings.isEmpty()) |
3166 | { | |
3167 | 4 | break; |
3168 | } | |
3169 | } | |
3170 | ||
3171 | 4 | if (sequence == null || seqMappings == null || seqMappings.isEmpty()) |
3172 | { | |
3173 | /* | |
3174 | * No ungapped mapped sequence in middle column - do nothing | |
3175 | */ | |
3176 | 0 | return 0; |
3177 | } | |
3178 | 4 | MappingUtils.addSearchResults(sr, sequence, |
3179 | sequence.findPosition(middleColumn), seqMappings); | |
3180 | 4 | return seqOffset; |
3181 | } | |
3182 | ||
3183 | /** | |
3184 | * synthesize a column selection if none exists so it covers the given | |
3185 | * selection group. if wholewidth is false, no column selection is made if the | |
3186 | * selection group covers the whole alignment width. | |
3187 | * | |
3188 | * @param sg | |
3189 | * @param wholewidth | |
3190 | */ | |
3191 | 0 | public void expandColSelection(SequenceGroup sg, boolean wholewidth) |
3192 | { | |
3193 | 0 | int sgs, sge; |
3194 | 0 | if (sg != null && (sgs = sg.getStartRes()) >= 0 |
3195 | && sg.getStartRes() <= (sge = sg.getEndRes()) | |
3196 | && !this.hasSelectedColumns()) | |
3197 | { | |
3198 | 0 | if (!wholewidth && alignment.getWidth() == (1 + sge - sgs)) |
3199 | { | |
3200 | // do nothing | |
3201 | 0 | return; |
3202 | } | |
3203 | 0 | if (colSel == null) |
3204 | { | |
3205 | 0 | colSel = new ColumnSelection(); |
3206 | } | |
3207 | 0 | for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++) |
3208 | { | |
3209 | 0 | colSel.addElement(cspos); |
3210 | } | |
3211 | } | |
3212 | } | |
3213 | ||
3214 | /** | |
3215 | * hold status of current selection group - defined on alignment or not. | |
3216 | */ | |
3217 | private boolean selectionIsDefinedGroup = false; | |
3218 | ||
3219 | 0 | @Override |
3220 | public boolean isSelectionDefinedGroup() | |
3221 | { | |
3222 | 0 | if (selectionGroup == null) |
3223 | { | |
3224 | 0 | return false; |
3225 | } | |
3226 | 0 | if (isSelectionGroupChanged(true)) |
3227 | { | |
3228 | 0 | selectionIsDefinedGroup = false; |
3229 | 0 | List<SequenceGroup> gps = alignment.getGroups(); |
3230 | 0 | if (gps == null || gps.size() == 0) |
3231 | { | |
3232 | 0 | selectionIsDefinedGroup = false; |
3233 | } | |
3234 | else | |
3235 | { | |
3236 | 0 | selectionIsDefinedGroup = gps.contains(selectionGroup); |
3237 | } | |
3238 | } | |
3239 | 0 | return selectionGroup.isDefined() || selectionIsDefinedGroup; |
3240 | } | |
3241 | ||
3242 | /** | |
3243 | * null, or currently highlighted results on this view | |
3244 | */ | |
3245 | private SearchResultsI searchResults = null; | |
3246 | ||
3247 | protected TreeModel currentTree = null; | |
3248 | ||
3249 | 12961 | @Override |
3250 | public boolean hasSearchResults() | |
3251 | { | |
3252 | 12961 | return searchResults != null; |
3253 | } | |
3254 | ||
3255 | 7 | @Override |
3256 | public void setSearchResults(SearchResultsI results) | |
3257 | { | |
3258 | 7 | searchResults = results; |
3259 | } | |
3260 | ||
3261 | 41 | @Override |
3262 | public SearchResultsI getSearchResults() | |
3263 | { | |
3264 | 41 | return searchResults; |
3265 | } | |
3266 | ||
3267 | 3552 | @Override |
3268 | public ContactListI getContactList(AlignmentAnnotation _aa, int column) | |
3269 | { | |
3270 | 3552 | return alignment.getContactListFor(_aa, column); |
3271 | } | |
3272 | ||
3273 | 139 | @Override |
3274 | public ContactMatrixI getContactMatrix( | |
3275 | AlignmentAnnotation alignmentAnnotation) | |
3276 | { | |
3277 | 139 | return alignment.getContactMatrixFor(alignmentAnnotation); |
3278 | } | |
3279 | ||
3280 | /** | |
3281 | * get the consensus sequence as displayed under the PID consensus annotation | |
3282 | * row. | |
3283 | * | |
3284 | * @return consensus sequence as a new sequence object | |
3285 | */ | |
3286 | 1 | public SequenceI getConsensusSeq() |
3287 | { | |
3288 | 1 | if (consensus == null) |
3289 | { | |
3290 | 0 | updateConsensus(null); |
3291 | } | |
3292 | 1 | if (consensus == null) |
3293 | { | |
3294 | 0 | return null; |
3295 | } | |
3296 | 1 | StringBuffer seqs = new StringBuffer(); |
3297 | 4 | for (int i = 0; i < consensus.annotations.length; i++) |
3298 | { | |
3299 | 3 | Annotation annotation = consensus.annotations[i]; |
3300 | 3 | if (annotation != null) |
3301 | { | |
3302 | 3 | String description = annotation.description; |
3303 | 3 | if (description != null && description.startsWith("[")) |
3304 | { | |
3305 | // consensus is a tie - just pick the first one | |
3306 | 1 | seqs.append(description.charAt(1)); |
3307 | } | |
3308 | else | |
3309 | { | |
3310 | 2 | seqs.append(annotation.displayCharacter); |
3311 | } | |
3312 | } | |
3313 | } | |
3314 | ||
3315 | 1 | SequenceI sq = new Sequence("Consensus", seqs.toString()); |
3316 | 1 | sq.setDescription("Percentage Identity Consensus " |
3317 | 1 | + ((ignoreGapsInConsensusCalculation) ? " without gaps" : "")); |
3318 | 1 | return sq; |
3319 | } | |
3320 | ||
3321 | // to do jal-4386 | |
3322 | 0 | public SequenceI getSSConsensusSeq() |
3323 | { | |
3324 | 0 | if (secondaryStructureConsensus == null) |
3325 | { | |
3326 | 0 | updateSecondaryStructureConsensus(null); |
3327 | } | |
3328 | 0 | if (secondaryStructureConsensus == null) |
3329 | { | |
3330 | 0 | return null; |
3331 | } | |
3332 | 0 | StringBuffer seqs = new StringBuffer(); |
3333 | // for (int i = 0; i < secondaryStructureConsensus.annotations.length; i++) | |
3334 | // { | |
3335 | // Annotation annotation = secondaryStructureConsensus.annotations[i]; | |
3336 | // if (annotation != null) | |
3337 | // { | |
3338 | // String description = annotation.description; | |
3339 | // if (description != null && description.startsWith("[")) | |
3340 | // { | |
3341 | // // consensus is a tie - just pick the first one | |
3342 | // seqs.append(description.charAt(1)); | |
3343 | // } | |
3344 | // else | |
3345 | // { | |
3346 | // seqs.append(annotation.displayCharacter); | |
3347 | // } | |
3348 | // } | |
3349 | // } | |
3350 | ||
3351 | 0 | SequenceI sq = new Sequence("Sec Str Consensus", seqs.toString()); |
3352 | 0 | sq.setDescription("Percentage Identity Sec Str Consensus " |
3353 | 0 | + ((ignoreGapsInConsensusCalculation) ? " without gaps" : "")); |
3354 | 0 | return sq; |
3355 | } | |
3356 | ||
3357 | 28 | @Override |
3358 | public void setCurrentTree(TreeModel tree) | |
3359 | { | |
3360 | 28 | currentTree = tree; |
3361 | } | |
3362 | ||
3363 | 50 | @Override |
3364 | public TreeModel getCurrentTree() | |
3365 | { | |
3366 | 50 | return currentTree; |
3367 | } | |
3368 | ||
3369 | 121 | @Override |
3370 | public AlignmentExportData getAlignExportData( | |
3371 | AlignExportSettingsI options) | |
3372 | { | |
3373 | 121 | AlignmentI alignmentToExport = null; |
3374 | 121 | String[] omitHidden = null; |
3375 | 121 | alignmentToExport = null; |
3376 | ||
3377 | 121 | if (hasHiddenColumns() && !options.isExportHiddenColumns()) |
3378 | { | |
3379 | 0 | omitHidden = getViewAsString(false, |
3380 | options.isExportHiddenSequences()); | |
3381 | } | |
3382 | ||
3383 | 121 | int[] alignmentStartEnd = new int[2]; |
3384 | 121 | if (hasHiddenRows() && options.isExportHiddenSequences()) |
3385 | { | |
3386 | 0 | alignmentToExport = getAlignment().getHiddenSequences() |
3387 | .getFullAlignment(); | |
3388 | } | |
3389 | else | |
3390 | { | |
3391 | 121 | alignmentToExport = getAlignment(); |
3392 | } | |
3393 | 121 | alignmentStartEnd = getAlignment().getHiddenColumns() |
3394 | .getVisibleStartAndEndIndex(alignmentToExport.getWidth()); | |
3395 | 121 | AlignmentExportData ed = new AlignmentExportData(alignmentToExport, |
3396 | omitHidden, alignmentStartEnd); | |
3397 | 121 | return ed; |
3398 | } | |
3399 | ||
3400 | /** | |
3401 | * flag set to indicate if structure views might be out of sync with sequences | |
3402 | * in the alignment | |
3403 | */ | |
3404 | ||
3405 | private boolean needToUpdateStructureViews = false; | |
3406 | ||
3407 | 0 | @Override |
3408 | public boolean isUpdateStructures() | |
3409 | { | |
3410 | 0 | return needToUpdateStructureViews; |
3411 | } | |
3412 | ||
3413 | 0 | @Override |
3414 | public void setUpdateStructures(boolean update) | |
3415 | { | |
3416 | 0 | needToUpdateStructureViews = update; |
3417 | } | |
3418 | ||
3419 | 1750 | @Override |
3420 | public boolean needToUpdateStructureViews() | |
3421 | { | |
3422 | 1750 | boolean update = needToUpdateStructureViews; |
3423 | 1750 | needToUpdateStructureViews = false; |
3424 | 1750 | return update; |
3425 | } | |
3426 | ||
3427 | 0 | @Override |
3428 | public void addSequenceGroup(SequenceGroup sequenceGroup) | |
3429 | { | |
3430 | 0 | alignment.addGroup(sequenceGroup); |
3431 | ||
3432 | 0 | Color col = sequenceGroup.idColour; |
3433 | 0 | if (col != null) |
3434 | { | |
3435 | 0 | col = col.brighter(); |
3436 | ||
3437 | 0 | for (SequenceI sq : sequenceGroup.getSequences()) |
3438 | { | |
3439 | 0 | setSequenceColour(sq, col); |
3440 | } | |
3441 | ||
3442 | 0 | List<AlignmentAnnotation> annotations = sequenceGroup.getAnnotationsFromTree(); |
3443 | 0 | if (annotations != null) { |
3444 | 0 | for (AlignmentAnnotation annot : annotations) { |
3445 | 0 | setAnnotationColour(annot, col); |
3446 | } | |
3447 | } | |
3448 | } | |
3449 | ||
3450 | 0 | if (codingComplement != null) |
3451 | { | |
3452 | 0 | SequenceGroup mappedGroup = MappingUtils |
3453 | .mapSequenceGroup(sequenceGroup, this, codingComplement); | |
3454 | 0 | if (mappedGroup.getSequences().size() > 0) |
3455 | { | |
3456 | 0 | codingComplement.getAlignment().addGroup(mappedGroup); |
3457 | ||
3458 | 0 | if (col != null) |
3459 | { | |
3460 | 0 | for (SequenceI seq : mappedGroup.getSequences()) |
3461 | { | |
3462 | 0 | codingComplement.setSequenceColour(seq, col); |
3463 | } | |
3464 | } | |
3465 | } | |
3466 | // propagate the structure view update flag according to our own setting | |
3467 | 0 | codingComplement.setUpdateStructures(needToUpdateStructureViews); |
3468 | } | |
3469 | } | |
3470 | ||
3471 | 34 | @Override |
3472 | public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly) | |
3473 | { | |
3474 | 34 | int start = 0; |
3475 | 34 | int end = 0; |
3476 | 34 | if (selectedRegionOnly && selectionGroup != null) |
3477 | { | |
3478 | 4 | start = selectionGroup.getStartRes(); |
3479 | 4 | end = selectionGroup.getEndRes() + 1; |
3480 | } | |
3481 | else | |
3482 | { | |
3483 | 30 | end = alignment.getWidth(); |
3484 | } | |
3485 | 34 | return (alignment.getHiddenColumns().getVisContigsIterator(start, end, |
3486 | false)); | |
3487 | } | |
3488 | ||
3489 | 133 | public void setSavedUpToDate(boolean s) |
3490 | { | |
3491 | 133 | setSavedUpToDate(s, QuitHandler.Message.UNSAVED_CHANGES); |
3492 | } | |
3493 | ||
3494 | 452 | public void setSavedUpToDate(boolean s, QuitHandler.Message m) |
3495 | { | |
3496 | 452 | Console.debug( |
3497 | "Setting " + this.getViewId() + " setSavedUpToDate to " + s); | |
3498 | 452 | savedUpToDate = s; |
3499 | 452 | QuitHandler.setMessage(m); |
3500 | } | |
3501 | ||
3502 | 4 | public boolean savedUpToDate() |
3503 | { | |
3504 | 4 | Console.debug("Returning " + this.getViewId() + " savedUpToDate value: " |
3505 | + savedUpToDate); | |
3506 | 4 | return savedUpToDate; |
3507 | } | |
3508 | } |